1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* Copyright © 2003-2011 Emulex. All rights reserved. */ 23 24 /* 25 * Source file containing the implementation of the driver statistics 26 * and related helper functions 27 */ 28 29 #include <oce_impl.h> 30 #include <oce_stat.h> 31 #include <oce_buf.h> 32 33 int pow10[5] = { 34 0, 35 10, 36 100, 37 1000, 38 10000 39 }; 40 41 /* 42 * function called by kstat to update the stats counters 43 * 44 * ksp - pointer to the kstats structure 45 * rw - flags defining read/write 46 * 47 * return DDI_SUCCESS => success, failure otherwise 48 */ 49 static int 50 oce_update_stats(kstat_t *ksp, int rw) 51 { 52 struct oce_dev *dev; 53 struct oce_stat *stats; 54 struct rx_port_stats *port_stats; 55 int ret; 56 57 if (rw == KSTAT_WRITE) { 58 return (EACCES); 59 } 60 61 dev = ksp->ks_private; 62 stats = (struct oce_stat *)ksp->ks_data; 63 port_stats = &dev->hw_stats->params.rsp.rx.port[dev->port_id]; 64 65 mutex_enter(&dev->dev_lock); 66 if (dev->suspended) { 67 mutex_exit(&dev->dev_lock); 68 return (EIO); 69 } 70 ret = oce_get_hw_stats(dev); 71 if (ret != DDI_SUCCESS) { 72 oce_log(dev, CE_WARN, MOD_CONFIG, 73 "Failed to get stats:%d", ret); 74 mutex_exit(&dev->dev_lock); 75 return (EIO); 76 } 77 78 /* update the stats */ 79 stats->rx_bytes_lo.value.ul = port_stats->rx_bytes_lsd; 80 stats->rx_bytes_hi.value.ul = port_stats->rx_bytes_msd; 81 82 stats->rx_frames.value.ul = port_stats->rx_total_frames; 83 stats->rx_errors.value.ul = port_stats->rx_crc_errors + 84 port_stats->rx_alignment_symbol_errors + 85 port_stats->rx_in_range_errors + 86 port_stats->rx_out_range_errors + 87 port_stats->rx_frame_too_long + 88 port_stats->rx_ip_checksum_errs + 89 port_stats->rx_tcp_checksum_errs + 90 port_stats->rx_udp_checksum_errs; 91 92 stats->rx_drops.value.ul = port_stats->rx_dropped_too_small + 93 port_stats->rx_dropped_too_short + 94 port_stats->rx_dropped_header_too_small + 95 port_stats->rx_dropped_tcp_length + 96 port_stats->rx_dropped_runt; 97 98 stats->tx_bytes_lo.value.ul = port_stats->tx_bytes_lsd; 99 stats->tx_bytes_hi.value.ul = port_stats->tx_bytes_msd; 100 101 stats->tx_frames.value.ul = port_stats->tx_unicast_frames + 102 port_stats->tx_multicast_frames + 103 port_stats->tx_broadcast_frames + 104 port_stats->tx_pause_frames + 105 port_stats->tx_control_frames; 106 stats->tx_errors.value.ul = dev->tx_errors; 107 108 stats->rx_unicast_frames.value.ul = 109 port_stats->rx_unicast_frames; 110 stats->rx_multicast_frames.value.ul = 111 port_stats->rx_multicast_frames; 112 stats->rx_broadcast_frames.value.ul = 113 port_stats->rx_broadcast_frames; 114 stats->rx_crc_errors.value.ul = 115 port_stats->rx_crc_errors; 116 117 stats->rx_alignment_symbol_errors.value.ul = 118 port_stats->rx_alignment_symbol_errors; 119 stats->rx_in_range_errors.value.ul = 120 port_stats->rx_in_range_errors; 121 stats->rx_out_range_errors.value.ul = 122 port_stats->rx_out_range_errors; 123 stats->rx_frame_too_long.value.ul = 124 port_stats->rx_frame_too_long; 125 stats->rx_address_match_errors.value.ul = 126 port_stats->rx_address_match_errors; 127 128 stats->rx_pause_frames.value.ul = 129 port_stats->rx_pause_frames; 130 stats->rx_control_frames.value.ul = 131 port_stats->rx_control_frames; 132 stats->rx_ip_checksum_errs.value.ul = 133 port_stats->rx_ip_checksum_errs; 134 stats->rx_tcp_checksum_errs.value.ul = 135 port_stats->rx_tcp_checksum_errs; 136 stats->rx_udp_checksum_errs.value.ul = 137 port_stats->rx_udp_checksum_errs; 138 stats->rx_fifo_overflow.value.ul = port_stats->rx_fifo_overflow; 139 stats->rx_input_fifo_overflow.value.ul = 140 port_stats->rx_input_fifo_overflow; 141 142 stats->tx_unicast_frames.value.ul = 143 port_stats->tx_unicast_frames; 144 stats->tx_multicast_frames.value.ul = 145 port_stats->tx_multicast_frames; 146 stats->tx_broadcast_frames.value.ul = 147 port_stats->tx_broadcast_frames; 148 stats->tx_pause_frames.value.ul = 149 port_stats->tx_pause_frames; 150 stats->tx_control_frames.value.ul = 151 port_stats->tx_control_frames; 152 153 154 stats->rx_drops_no_pbuf.value.ul = 155 dev->hw_stats->params.rsp.rx.rx_drops_no_pbuf; 156 stats->rx_drops_no_txpb.value.ul = 157 dev->hw_stats->params.rsp.rx.rx_drops_no_txpb; 158 stats->rx_drops_no_erx_descr.value.ul = 159 dev->hw_stats->params.rsp.rx.rx_drops_no_erx_descr; 160 stats->rx_drops_no_tpre_descr.value.ul = 161 dev->hw_stats->params.rsp.rx.rx_drops_no_tpre_descr; 162 stats->rx_drops_too_many_frags.value.ul = 163 dev->hw_stats->params.rsp.rx.rx_drops_too_many_frags; 164 stats->rx_drops_invalid_ring.value.ul = 165 dev->hw_stats->params.rsp.rx.rx_drops_invalid_ring; 166 stats->rx_drops_mtu.value.ul = 167 dev->hw_stats->params.rsp.rx.rx_drops_mtu; 168 169 stats->rx_dropped_too_small.value.ul = 170 port_stats->rx_dropped_too_small; 171 stats->rx_dropped_too_short.value.ul = 172 port_stats->rx_dropped_too_short; 173 stats->rx_dropped_header_too_small.value.ul = 174 port_stats->rx_dropped_header_too_small; 175 stats->rx_dropped_tcp_length.value.ul = 176 port_stats->rx_dropped_tcp_length; 177 stats->rx_dropped_runt.value.ul = 178 port_stats->rx_dropped_runt; 179 180 stats->rx_drops_no_fragments.value.ul = 181 dev->hw_stats->params.rsp.err_rx.rx_drops_no_fragments[0]; 182 183 mutex_exit(&dev->dev_lock); 184 return (DDI_SUCCESS); 185 } /* oce_update_stats */ 186 187 /* 188 * function to setup the kstat_t structure for the device and install it 189 * 190 * dev - software handle to the device 191 * 192 * return DDI_SUCCESS => success, failure otherwise 193 */ 194 int 195 oce_stat_init(struct oce_dev *dev) 196 { 197 struct oce_stat *stats; 198 uint32_t num_stats = sizeof (struct oce_stat) / 199 sizeof (kstat_named_t); 200 201 /* allocate the kstat */ 202 dev->oce_kstats = kstat_create(OCE_MOD_NAME, dev->dev_id, "stats", 203 "net", KSTAT_TYPE_NAMED, 204 num_stats, 0); 205 if (dev->oce_kstats == NULL) { 206 oce_log(dev, CE_NOTE, MOD_CONFIG, 207 "kstat creation failed: 0x%p", 208 (void *)dev->oce_kstats); 209 return (DDI_FAILURE); 210 } 211 212 /* allocate the device copy of the stats */ 213 dev->stats_dbuf = oce_alloc_dma_buffer(dev, 214 sizeof (struct mbx_get_nic_stats), 215 NULL, DDI_DMA_CONSISTENT); 216 if (dev->stats_dbuf == NULL) { 217 oce_log(dev, CE_NOTE, MOD_CONFIG, 218 "Could not allocate stats_dbuf: %p", 219 (void *)dev->stats_dbuf); 220 kstat_delete(dev->oce_kstats); 221 return (DDI_FAILURE); 222 } 223 dev->hw_stats = (struct mbx_get_nic_stats *)DBUF_VA(dev->stats_dbuf); 224 225 /* initialize the counters */ 226 stats = (struct oce_stat *)dev->oce_kstats->ks_data; 227 kstat_named_init(&stats->rx_bytes_hi, "rx bytes msd", KSTAT_DATA_ULONG); 228 kstat_named_init(&stats->rx_bytes_lo, "rx bytes lsd", KSTAT_DATA_ULONG); 229 230 kstat_named_init(&stats->rx_frames, "rx frames", KSTAT_DATA_ULONG); 231 kstat_named_init(&stats->rx_errors, "rx errors", KSTAT_DATA_ULONG); 232 kstat_named_init(&stats->rx_drops, "rx drops", KSTAT_DATA_ULONG); 233 234 kstat_named_init(&stats->tx_bytes_hi, "tx bytes msd", KSTAT_DATA_ULONG); 235 kstat_named_init(&stats->tx_bytes_lo, "tx bytes lsd", KSTAT_DATA_ULONG); 236 237 kstat_named_init(&stats->tx_frames, "tx frames", KSTAT_DATA_ULONG); 238 kstat_named_init(&stats->tx_errors, "tx errors", KSTAT_DATA_ULONG); 239 240 kstat_named_init(&stats->rx_unicast_frames, 241 "rx unicast frames", KSTAT_DATA_ULONG); 242 kstat_named_init(&stats->rx_multicast_frames, 243 "rx multicast frames", KSTAT_DATA_ULONG); 244 kstat_named_init(&stats->rx_broadcast_frames, 245 "rx broadcast frames", KSTAT_DATA_ULONG); 246 kstat_named_init(&stats->rx_crc_errors, 247 "rx crc errors", KSTAT_DATA_ULONG); 248 249 kstat_named_init(&stats->rx_alignment_symbol_errors, 250 "rx alignment symbol errors", KSTAT_DATA_ULONG); 251 kstat_named_init(&stats->rx_in_range_errors, 252 "rx in range errors", KSTAT_DATA_ULONG); 253 kstat_named_init(&stats->rx_out_range_errors, 254 "rx out range errors", KSTAT_DATA_ULONG); 255 kstat_named_init(&stats->rx_frame_too_long, 256 "rx frame too long", KSTAT_DATA_ULONG); 257 kstat_named_init(&stats->rx_address_match_errors, 258 "rx address match errors", KSTAT_DATA_ULONG); 259 260 kstat_named_init(&stats->rx_pause_frames, 261 "rx pause frames", KSTAT_DATA_ULONG); 262 kstat_named_init(&stats->rx_control_frames, 263 "rx control frames", KSTAT_DATA_ULONG); 264 kstat_named_init(&stats->rx_ip_checksum_errs, 265 "rx ip checksum errors", KSTAT_DATA_ULONG); 266 kstat_named_init(&stats->rx_tcp_checksum_errs, 267 "rx tcp checksum errors", KSTAT_DATA_ULONG); 268 kstat_named_init(&stats->rx_udp_checksum_errs, 269 "rx udp checksum errors", KSTAT_DATA_ULONG); 270 kstat_named_init(&stats->rx_fifo_overflow, 271 "rx fifo overflow", KSTAT_DATA_ULONG); 272 kstat_named_init(&stats->rx_input_fifo_overflow, 273 "rx input fifo overflow", KSTAT_DATA_ULONG); 274 275 kstat_named_init(&stats->tx_unicast_frames, 276 "tx unicast frames", KSTAT_DATA_ULONG); 277 kstat_named_init(&stats->tx_multicast_frames, 278 "tx multicast frames", KSTAT_DATA_ULONG); 279 kstat_named_init(&stats->tx_broadcast_frames, 280 "tx broadcast frames", KSTAT_DATA_ULONG); 281 kstat_named_init(&stats->tx_pause_frames, 282 "tx pause frames", KSTAT_DATA_ULONG); 283 kstat_named_init(&stats->tx_control_frames, 284 "tx control frames", KSTAT_DATA_ULONG); 285 286 287 kstat_named_init(&stats->rx_drops_no_pbuf, 288 "rx_drops_no_pbuf", KSTAT_DATA_ULONG); 289 kstat_named_init(&stats->rx_drops_no_txpb, 290 "rx_drops_no_txpb", KSTAT_DATA_ULONG); 291 kstat_named_init(&stats->rx_drops_no_erx_descr, 292 "rx_drops_no_erx_descr", KSTAT_DATA_ULONG); 293 kstat_named_init(&stats->rx_drops_no_tpre_descr, 294 "rx_drops_no_tpre_descr", KSTAT_DATA_ULONG); 295 kstat_named_init(&stats->rx_drops_too_many_frags, 296 "rx_drops_too_many_frags", KSTAT_DATA_ULONG); 297 kstat_named_init(&stats->rx_drops_invalid_ring, 298 "rx_drops_invalid_ring", KSTAT_DATA_ULONG); 299 kstat_named_init(&stats->rx_drops_mtu, 300 "rx_drops_mtu", KSTAT_DATA_ULONG); 301 302 kstat_named_init(&stats->rx_dropped_too_small, 303 "rx_dropped_too_small", KSTAT_DATA_ULONG); 304 kstat_named_init(&stats->rx_dropped_too_short, 305 "rx_dropped_too_short", KSTAT_DATA_ULONG); 306 kstat_named_init(&stats->rx_dropped_header_too_small, 307 "rx_dropped_header_too_small", KSTAT_DATA_ULONG); 308 kstat_named_init(&stats->rx_dropped_tcp_length, 309 "rx_dropped_tcp_length", KSTAT_DATA_ULONG); 310 kstat_named_init(&stats->rx_dropped_runt, 311 "rx_dropped_runt", KSTAT_DATA_ULONG); 312 313 kstat_named_init(&stats->rx_drops_no_fragments, 314 "rx_drop_no_frag", KSTAT_DATA_ULONG); 315 316 317 dev->oce_kstats->ks_update = oce_update_stats; 318 dev->oce_kstats->ks_private = (void *)dev; 319 kstat_install(dev->oce_kstats); 320 321 return (DDI_SUCCESS); 322 } /* oce_stat_init */ 323 324 /* 325 * function to undo initialization done in oce_stat_init 326 * 327 * dev - software handle to the device 328 * 329 * return none 330 */ 331 void 332 oce_stat_fini(struct oce_dev *dev) 333 { 334 oce_free_dma_buffer(dev, dev->stats_dbuf); 335 dev->hw_stats = NULL; 336 dev->stats_dbuf = NULL; 337 kstat_delete(dev->oce_kstats); 338 dev->oce_kstats = NULL; 339 } /* oce_stat_fini */ 340 341 /* 342 * GLDv3 entry for statistic query 343 */ 344 int 345 oce_m_stat(void *arg, uint_t stat, uint64_t *val) 346 { 347 struct oce_dev *dev = arg; 348 struct oce_stat *stats; 349 struct rx_port_stats *port_stats; 350 351 stats = (struct oce_stat *)dev->oce_kstats->ks_data; 352 port_stats = &dev->hw_stats->params.rsp.rx.port[dev->port_id]; 353 354 mutex_enter(&dev->dev_lock); 355 356 if (dev->suspended || 357 (dev->state & STATE_MAC_STOPPING) || 358 !(dev->state & STATE_MAC_STARTED)) { 359 mutex_exit(&dev->dev_lock); 360 return (EIO); 361 } 362 363 switch (stat) { 364 case MAC_STAT_IFSPEED: { 365 struct link_status link = {0}; 366 if (dev->link_speed < 0) { 367 (void) oce_get_link_status(dev, &link); 368 dev->link_speed = link.qos_link_speed ? 369 link.qos_link_speed * 10 : 370 pow10[link.mac_speed]; 371 } 372 *val = dev->link_speed * 1000000ull; 373 } 374 break; 375 376 case MAC_STAT_RBYTES: 377 stats->rx_bytes_lo.value.ul = port_stats->rx_bytes_lsd; 378 stats->rx_bytes_hi.value.ul = port_stats->rx_bytes_msd; 379 *val = (uint64_t)stats->rx_bytes_hi.value.ul << 32 | 380 (uint64_t)stats->rx_bytes_lo.value.ul; 381 break; 382 383 case MAC_STAT_IPACKETS: 384 stats->rx_frames.value.ul = port_stats->rx_total_frames; 385 *val = stats->rx_frames.value.ul; 386 break; 387 388 case MAC_STAT_OBYTES: 389 stats->tx_bytes_lo.value.ul = port_stats->tx_bytes_lsd; 390 stats->tx_bytes_hi.value.ul = port_stats->tx_bytes_msd; 391 *val = (uint64_t)stats->tx_bytes_hi.value.ul << 32 | 392 (uint64_t)stats->tx_bytes_lo.value.ul; 393 break; 394 395 case MAC_STAT_OPACKETS: 396 stats->tx_frames.value.ul = port_stats->tx_unicast_frames + 397 port_stats->tx_multicast_frames + 398 port_stats->tx_broadcast_frames + 399 port_stats->tx_pause_frames + 400 port_stats->tx_control_frames; 401 *val = stats->tx_frames.value.ul; 402 break; 403 404 case MAC_STAT_BRDCSTRCV: 405 stats->rx_broadcast_frames.value.ul = 406 port_stats->rx_broadcast_frames; 407 *val = stats->rx_broadcast_frames.value.ul; 408 break; 409 410 case MAC_STAT_MULTIRCV: 411 stats->rx_multicast_frames.value.ul = 412 port_stats->rx_multicast_frames; 413 *val = stats->rx_multicast_frames.value.ul; 414 break; 415 416 case MAC_STAT_MULTIXMT: 417 stats->tx_multicast_frames.value.ul = 418 port_stats->tx_multicast_frames; 419 *val = stats->tx_multicast_frames.value.ul; 420 break; 421 422 case MAC_STAT_BRDCSTXMT: 423 stats->tx_broadcast_frames.value.ul = 424 port_stats->tx_broadcast_frames; 425 *val = stats->tx_broadcast_frames.value.ul; 426 break; 427 428 case MAC_STAT_NORCVBUF: 429 stats->rx_fifo_overflow.value.ul = 430 port_stats->rx_fifo_overflow; 431 *val = stats->rx_fifo_overflow.value.ul; 432 break; 433 434 case MAC_STAT_IERRORS: 435 stats->rx_errors.value.ul = port_stats->rx_crc_errors + 436 port_stats->rx_alignment_symbol_errors + 437 port_stats->rx_in_range_errors + 438 port_stats->rx_out_range_errors + 439 port_stats->rx_frame_too_long + 440 port_stats->rx_ip_checksum_errs + 441 port_stats->rx_tcp_checksum_errs + 442 port_stats->rx_udp_checksum_errs; 443 *val = stats->rx_errors.value.ul; 444 break; 445 446 case MAC_STAT_NOXMTBUF: 447 *val = dev->tx_noxmtbuf; 448 break; 449 450 case MAC_STAT_OERRORS: 451 *val = stats->tx_errors.value.ul; 452 break; 453 454 case ETHER_STAT_LINK_DUPLEX: 455 if (dev->state & STATE_MAC_STARTED) 456 *val = LINK_DUPLEX_FULL; 457 else 458 *val = LINK_DUPLEX_UNKNOWN; 459 break; 460 461 case ETHER_STAT_ALIGN_ERRORS: 462 stats->rx_alignment_symbol_errors.value.ul = 463 port_stats->rx_alignment_symbol_errors; 464 *val = port_stats->rx_alignment_symbol_errors; 465 break; 466 467 case ETHER_STAT_FCS_ERRORS: 468 stats->rx_crc_errors.value.ul = 469 port_stats->rx_crc_errors; 470 *val = port_stats->rx_crc_errors; 471 break; 472 473 case ETHER_STAT_MACRCV_ERRORS: 474 stats->rx_errors.value.ul = port_stats->rx_crc_errors + 475 port_stats->rx_alignment_symbol_errors + 476 port_stats->rx_in_range_errors + 477 port_stats->rx_out_range_errors + 478 port_stats->rx_frame_too_long + 479 port_stats->rx_ip_checksum_errs + 480 port_stats->rx_tcp_checksum_errs + 481 port_stats->rx_udp_checksum_errs; 482 483 *val = stats->rx_errors.value.ul; 484 break; 485 486 case ETHER_STAT_MACXMT_ERRORS: 487 *val = stats->tx_errors.value.ul; 488 break; 489 490 case ETHER_STAT_TOOLONG_ERRORS: 491 stats->rx_frame_too_long.value.ul = 492 port_stats->rx_frame_too_long; 493 *val = port_stats->rx_frame_too_long; 494 break; 495 496 case ETHER_STAT_CAP_PAUSE: 497 case ETHER_STAT_LINK_PAUSE: 498 if (dev->flow_control & OCE_FC_TX && 499 dev->flow_control & OCE_FC_RX) 500 *val = LINK_FLOWCTRL_BI; 501 else if (dev->flow_control == OCE_FC_TX) 502 *val = LINK_FLOWCTRL_TX; 503 else if (dev->flow_control == OCE_FC_RX) 504 *val = LINK_FLOWCTRL_RX; 505 else if (dev->flow_control == 0) 506 *val = LINK_FLOWCTRL_NONE; 507 break; 508 509 default: 510 mutex_exit(&dev->dev_lock); 511 return (ENOTSUP); 512 } 513 mutex_exit(&dev->dev_lock); 514 return (0); 515 } /* oce_m_stat */ 516