Print this page
NEX-1890 update oce from source provided by Emulex


   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 +


 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);


 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 */


   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 /*
  23  * Copyright (c) 2009-2012 Emulex. All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 
  28 
  29 /*
  30  * Source file containing the implementation of the driver statistics
  31  * and related helper functions
  32  */
  33 
  34 #include <oce_impl.h>
  35 #include <oce_stat.h>
  36 #include <oce_buf.h>
  37 







  38 
  39 static int
  40 oce_update_lancer_stats(struct oce_dev *dev, struct oce_stat *stats)
  41 {
  42         struct mbx_get_pport_stats *hw_stats;
  43         int ret;
  44 
  45         hw_stats = (struct mbx_get_pport_stats *)DBUF_VA(dev->stats_dbuf);
  46         ret = oce_get_pport_stats(dev, MBX_ASYNC_MQ);
  47         if (ret != DDI_SUCCESS) {
  48                 oce_log(dev, CE_WARN, MOD_CONFIG,
  49                     "Failed to get stats:%d", ret);
  50                 return (EIO);
  51         }
  52 
  53         /* update the stats */
  54         stats->rx_bytes_lo.value.ul =
  55             hw_stats->params.rsp.pport_stats.rx_bytes_lo;
  56         stats->rx_bytes_hi.value.ul =
  57             hw_stats->params.rsp.pport_stats.rx_bytes_hi;
  58 
  59         stats->rx_frames.value.ul =
  60             hw_stats->params.rsp.pport_stats.rx_packets_lo;
  61         stats->rx_errors.value.ul =
  62             hw_stats->params.rsp.pport_stats.rx_crc_errors_lo +
  63             hw_stats->params.rsp.pport_stats.rx_alignment_errors_lo +
  64             hw_stats->params.rsp.pport_stats.rx_symbol_errors_lo +
  65             hw_stats->params.rsp.pport_stats.rx_in_range_errors +
  66             hw_stats->params.rsp.pport_stats.rx_out_of_range_errors +
  67             hw_stats->params.rsp.pport_stats.rx_frames_too_long_lo +
  68             hw_stats->params.rsp.pport_stats.rx_ip_checksum_errors +
  69             hw_stats->params.rsp.pport_stats.rx_tcp_checksum_errors +
  70             hw_stats->params.rsp.pport_stats.rx_udp_checksum_errors;
  71 
  72         stats->rx_drops.value.ul =
  73             hw_stats->params.rsp.pport_stats.rx_dropped_too_small +
  74             hw_stats->params.rsp.pport_stats.rx_dropped_too_short +
  75             hw_stats->params.rsp.pport_stats.rx_dropped_header_too_small +
  76             hw_stats->params.rsp.pport_stats.rx_dropped_invalid_tcp_length +
  77             hw_stats->params.rsp.pport_stats.rx_dropped_runt;
  78 
  79         stats->tx_bytes_lo.value.ul =
  80             hw_stats->params.rsp.pport_stats.tx_packets_lo;
  81         stats->tx_bytes_hi.value.ul =
  82             hw_stats->params.rsp.pport_stats.tx_packets_hi;
  83 
  84         stats->tx_frames.value.ul =
  85             hw_stats->params.rsp.pport_stats.tx_unicast_packets_lo +
  86             hw_stats->params.rsp.pport_stats.tx_multicast_packets_lo +
  87             hw_stats->params.rsp.pport_stats.tx_broadcast_packets_lo +
  88             hw_stats->params.rsp.pport_stats.tx_pause_frames_lo +
  89             hw_stats->params.rsp.pport_stats.tx_control_frames_lo;
  90 
  91         /* Update all Wq errors */
  92         stats->tx_errors.value.ul = dev->tx_errors;
  93 
  94         stats->rx_unicast_frames.value.ul =
  95             hw_stats->params.rsp.pport_stats.rx_unicast_packets_lo;
  96         stats->rx_multicast_frames.value.ul =
  97             hw_stats->params.rsp.pport_stats.rx_multicast_packets_lo;
  98         stats->rx_broadcast_frames.value.ul =
  99             hw_stats->params.rsp.pport_stats.rx_broadcast_packets_lo;
 100         stats->rx_crc_errors.value.ul =
 101             hw_stats->params.rsp.pport_stats.rx_crc_errors_lo;
 102 
 103         stats->rx_alignment_symbol_errors.value.ul =
 104             hw_stats->params.rsp.pport_stats.rx_alignment_errors_lo +
 105             hw_stats->params.rsp.pport_stats.rx_symbol_errors_lo;
 106         stats->rx_in_range_errors.value.ul =
 107             hw_stats->params.rsp.pport_stats.rx_in_range_errors;
 108         stats->rx_out_range_errors.value.ul =
 109             hw_stats->params.rsp.pport_stats.rx_out_of_range_errors;
 110         stats->rx_frame_too_long.value.ul =
 111             hw_stats->params.rsp.pport_stats.rx_frames_too_long_lo;
 112         stats->rx_address_match_errors.value.ul =
 113             hw_stats->params.rsp.pport_stats.rx_address_match_errors;
 114 
 115         stats->rx_pause_frames.value.ul =
 116             hw_stats->params.rsp.pport_stats.rx_pause_frames_lo;
 117         stats->rx_control_frames.value.ul =
 118             hw_stats->params.rsp.pport_stats.rx_control_frames_lo;
 119         stats->rx_ip_checksum_errs.value.ul =
 120             hw_stats->params.rsp.pport_stats.rx_ip_checksum_errors;
 121         stats->rx_tcp_checksum_errs.value.ul =
 122             hw_stats->params.rsp.pport_stats.rx_tcp_checksum_errors;
 123         stats->rx_udp_checksum_errs.value.ul =
 124             hw_stats->params.rsp.pport_stats.rx_udp_checksum_errors;
 125         stats->rx_fifo_overflow.value.ul =
 126             hw_stats->params.rsp.pport_stats.rx_fifo_overflow;
 127         stats->rx_input_fifo_overflow.value.ul =
 128             hw_stats->params.rsp.pport_stats.rx_input_fifo_overflow;
 129 
 130         stats->tx_unicast_frames.value.ul =
 131             hw_stats->params.rsp.pport_stats.tx_unicast_packets_lo;
 132         stats->tx_multicast_frames.value.ul =
 133             hw_stats->params.rsp.pport_stats.tx_multicast_packets_lo;
 134         stats->tx_broadcast_frames.value.ul =
 135             hw_stats->params.rsp.pport_stats.tx_broadcast_packets_lo;
 136         stats->tx_pause_frames.value.ul =
 137             hw_stats->params.rsp.pport_stats.tx_pause_frames_lo;
 138         stats->tx_control_frames.value.ul =
 139             hw_stats->params.rsp.pport_stats.tx_control_frames_lo;
 140 
 141 
 142         stats->rx_drops_too_many_frags.value.ul =
 143             hw_stats->params.rsp.pport_stats.rx_drops_too_many_frags_lo;
 144         stats->rx_drops_invalid_ring.value.ul =
 145             hw_stats->params.rsp.pport_stats.rx_drops_invalid_queue;
 146         stats->rx_drops_mtu.value.ul =
 147             hw_stats->params.rsp.pport_stats.rx_drops_mtu_lo;
 148 
 149         stats->rx_dropped_too_small.value.ul =
 150             hw_stats->params.rsp.pport_stats.rx_dropped_too_small;
 151         stats->rx_dropped_too_short.value.ul =
 152             hw_stats->params.rsp.pport_stats.rx_dropped_too_short;
 153         stats->rx_dropped_header_too_small.value.ul =
 154             hw_stats->params.rsp.pport_stats.rx_dropped_header_too_small;
 155         stats->rx_dropped_tcp_length.value.ul =
 156             hw_stats->params.rsp.pport_stats.rx_dropped_invalid_tcp_length;
 157         stats->rx_dropped_runt.value.ul =
 158             hw_stats->params.rsp.pport_stats.rx_dropped_runt;
 159 
 160         return (DDI_SUCCESS);
 161 }
 162 
 163 /*
 164  * function called by kstat to update the stats counters
 165  *
 166  * ksp - pointer to the kstats structure
 167  * rw - flags defining read/write
 168  *
 169  * return DDI_SUCCESS => success, failure otherwise
 170  */
 171 static int
 172 oce_update_be_stats(struct oce_dev *dev, struct oce_stat *stats)
 173 {
 174         struct mbx_get_nic_stats *fwcmd;
 175         int i, ret;


 176 
 177         ret = oce_get_hw_stats(dev, MBX_ASYNC_MQ);













 178         if (ret != DDI_SUCCESS) {



 179                 return (EIO);
 180         }
 181 
 182         /* update the stats */
 183         fwcmd = (struct mbx_get_nic_stats *)DBUF_VA(dev->stats_dbuf);
 184         if (dev->chip_rev == OC_CNA_GEN2) {
 185                 struct be_hw_stats_v0 *hw_stats = &fwcmd->params.rsp.v0;
 186                 struct rx_stats_v0 *rx_stats = &hw_stats->rx;
 187                 struct rx_port_stats_v0 *port_stats =
 188                     &rx_stats->port[dev->port_id];
 189                 struct rx_err_stats_v0 *err_stats = &hw_stats->err_rx;
 190 
 191                 stats->rx_bytes_lo.value.ul = port_stats->rx_bytes_lsd;
 192                 stats->rx_bytes_hi.value.ul = port_stats->rx_bytes_msd;

 193                 stats->rx_frames.value.ul = port_stats->rx_total_frames;
 194                 stats->rx_errors.value.ul = port_stats->rx_crc_errors +
 195                     port_stats->rx_alignment_symbol_errors +
 196                     port_stats->rx_in_range_errors +
 197                     port_stats->rx_out_range_errors +
 198                     port_stats->rx_frame_too_long +
 199                     port_stats->rx_ip_checksum_errs +
 200                     port_stats->rx_tcp_checksum_errs +
 201                     port_stats->rx_udp_checksum_errs;
 202 
 203                 stats->rx_drops.value.ul = port_stats->rx_dropped_too_small +
 204                     port_stats->rx_dropped_too_short +
 205                     port_stats->rx_dropped_header_too_small +
 206                     port_stats->rx_dropped_tcp_length +
 207                     port_stats->rx_dropped_runt;
 208 
 209                 stats->tx_bytes_lo.value.ul = port_stats->tx_bytes_lsd;
 210                 stats->tx_bytes_hi.value.ul = port_stats->tx_bytes_msd;
 211 
 212                 stats->tx_frames.value.ul = port_stats->tx_unicast_frames +


 246                     port_stats->rx_tcp_checksum_errs;
 247                 stats->rx_udp_checksum_errs.value.ul =
 248                     port_stats->rx_udp_checksum_errs;
 249                 stats->rx_fifo_overflow.value.ul = port_stats->rx_fifo_overflow;
 250                 stats->rx_input_fifo_overflow.value.ul =
 251                     port_stats->rx_input_fifo_overflow;
 252 
 253                 stats->tx_unicast_frames.value.ul =
 254                     port_stats->tx_unicast_frames;
 255                 stats->tx_multicast_frames.value.ul =
 256                     port_stats->tx_multicast_frames;
 257                 stats->tx_broadcast_frames.value.ul =
 258                     port_stats->tx_broadcast_frames;
 259                 stats->tx_pause_frames.value.ul =
 260                     port_stats->tx_pause_frames;
 261                 stats->tx_control_frames.value.ul =
 262                     port_stats->tx_control_frames;
 263 
 264 
 265                 stats->rx_drops_no_pbuf.value.ul =
 266                     rx_stats->rx_drops_no_pbuf;
 267                 stats->rx_drops_no_txpb.value.ul =
 268                     rx_stats->rx_drops_no_txpb;
 269                 stats->rx_drops_no_erx_descr.value.ul =
 270                     rx_stats->rx_drops_no_erx_descr;
 271                 stats->rx_drops_no_tpre_descr.value.ul =
 272                     rx_stats->rx_drops_no_tpre_descr;
 273                 stats->rx_drops_too_many_frags.value.ul =
 274                     rx_stats->rx_drops_too_many_frags;
 275                 stats->rx_drops_invalid_ring.value.ul =
 276                     rx_stats->rx_drops_invalid_ring;
 277                 stats->rx_drops_mtu.value.ul =
 278                     rx_stats->rx_drops_mtu;
 279 
 280                 stats->rx_dropped_too_small.value.ul =
 281                     port_stats->rx_dropped_too_small;
 282                 stats->rx_dropped_too_short.value.ul =
 283                     port_stats->rx_dropped_too_short;
 284                 stats->rx_dropped_header_too_small.value.ul =
 285                     port_stats->rx_dropped_header_too_small;
 286                 stats->rx_dropped_tcp_length.value.ul =
 287                     port_stats->rx_dropped_tcp_length;
 288                 stats->rx_dropped_runt.value.ul =
 289                     port_stats->rx_dropped_runt;
 290 
 291                 stats->rx_drops_no_fragments.value.ul = 0;
 292                 for (i = 0; i < dev->nrqs; i++) {
 293                         stats->rx_drops_no_fragments.value.ul +=
 294                             err_stats->rx_drops_no_fragments[dev->rq[i].rq_id];
 295                 }
 296 
 297                 stats->rx_priority_pause_frames.value.ul = 0;
 298                 stats->pmem_fifo_overflow_drop.value.ul = 0;
 299                 if (dev->port_id) {
 300                         stats->jabber_events.value.ul =
 301                             rx_stats->port1_jabber_events;
 302                 } else {
 303                         stats->jabber_events.value.ul =
 304                             rx_stats->port0_jabber_events;
 305                 }
 306                 stats->forwarded_packets.value.ul = rx_stats->forwarded_packets;
 307 
 308         } else {
 309                 struct be_hw_stats_v1 *hw_stats = &fwcmd->params.rsp.v1;
 310                 struct rx_stats_v1 *rx_stats = &hw_stats->rx;
 311                 struct rx_port_stats_v1 *port_stats =
 312                     &rx_stats->port[dev->port_id];
 313                 struct rx_err_stats_v1 *err_stats = &hw_stats->err_rx;
 314 
 315                 stats->rx_bytes_lo.value.ul = port_stats->rx_bytes_lsd;
 316                 stats->rx_bytes_hi.value.ul = port_stats->rx_bytes_msd;
 317                 stats->rx_frames.value.ul = port_stats->rx_total_frames;
 318                 stats->rx_errors.value.ul = port_stats->rx_crc_errors +
 319                     port_stats->rx_alignment_symbol_errors +
 320                     port_stats->rx_in_range_errors +
 321                     port_stats->rx_out_range_errors +
 322                     port_stats->rx_frame_too_long +
 323                     port_stats->rx_ip_checksum_errs +
 324                     port_stats->rx_tcp_checksum_errs +
 325                     port_stats->rx_udp_checksum_errs;
 326 
 327                 stats->rx_drops.value.ul = port_stats->rx_dropped_too_small +
 328                     port_stats->rx_dropped_too_short +
 329                     port_stats->rx_dropped_header_too_small +
 330                     port_stats->rx_dropped_tcp_length +
 331                     port_stats->rx_dropped_runt;
 332 
 333                 stats->tx_bytes_lo.value.ul = port_stats->tx_bytes_lsd;
 334                 stats->tx_bytes_hi.value.ul = port_stats->tx_bytes_msd;
 335 
 336                 stats->tx_frames.value.ul = port_stats->tx_unicast_frames +
 337                     port_stats->tx_multicast_frames +
 338                     port_stats->tx_broadcast_frames +
 339                     port_stats->tx_pause_frames +
 340                     port_stats->tx_control_frames;
 341                 stats->tx_errors.value.ul = dev->tx_errors;
 342 
 343                 stats->rx_unicast_frames.value.ul =
 344                     port_stats->rx_non_switched_unicast_frames +
 345                     port_stats->rx_switched_unicast_packets;
 346                 stats->rx_multicast_frames.value.ul =
 347                     port_stats->rx_non_switched_multicast_frames +
 348                     port_stats->rx_switched_multicast_packets;
 349                 stats->rx_broadcast_frames.value.ul =
 350                     port_stats->rx_non_switched_broadcast_frames +
 351                     port_stats->rx_switched_broadcast_packets;
 352                 stats->rx_crc_errors.value.ul =
 353                     port_stats->rx_crc_errors;
 354 
 355                 stats->rx_alignment_symbol_errors.value.ul =
 356                     port_stats->rx_alignment_symbol_errors;
 357                 stats->rx_in_range_errors.value.ul =
 358                     port_stats->rx_in_range_errors;
 359                 stats->rx_out_range_errors.value.ul =
 360                     port_stats->rx_out_range_errors;
 361                 stats->rx_frame_too_long.value.ul =
 362                     port_stats->rx_frame_too_long;
 363                 stats->rx_address_match_errors.value.ul =
 364                     port_stats->rx_address_match_errors;
 365 
 366                 stats->rx_pause_frames.value.ul =
 367                     port_stats->rx_pause_frames;
 368                 stats->rx_control_frames.value.ul =
 369                     port_stats->rx_control_frames;
 370                 stats->rx_ip_checksum_errs.value.ul =
 371                     port_stats->rx_ip_checksum_errs;
 372                 stats->rx_tcp_checksum_errs.value.ul =
 373                     port_stats->rx_tcp_checksum_errs;
 374                 stats->rx_udp_checksum_errs.value.ul =
 375                     port_stats->rx_udp_checksum_errs;
 376                 stats->rx_fifo_overflow.value.ul =
 377                     port_stats->rxpp_fifo_overflow_drop;
 378                 stats->rx_input_fifo_overflow.value.ul =
 379                     port_stats->rx_input_fifo_overflow_drop;
 380 
 381                 stats->tx_unicast_frames.value.ul =
 382                     port_stats->tx_unicast_frames;
 383                 stats->tx_multicast_frames.value.ul =
 384                     port_stats->tx_multicast_frames;
 385                 stats->tx_broadcast_frames.value.ul =
 386                     port_stats->tx_broadcast_frames;
 387                 stats->tx_pause_frames.value.ul =
 388                     port_stats->tx_pause_frames;
 389                 stats->tx_control_frames.value.ul =
 390                     port_stats->tx_control_frames;
 391 
 392 
 393                 stats->rx_drops_no_pbuf.value.ul =
 394                     rx_stats->rx_drops_no_pbuf;
 395                 stats->rx_drops_no_txpb.value.ul =
 396                     rx_stats->rx_drops_no_txpb;
 397                 stats->rx_drops_no_erx_descr.value.ul =
 398                     rx_stats->rx_drops_no_erx_descr;
 399                 stats->rx_drops_no_tpre_descr.value.ul =
 400                     rx_stats->rx_drops_no_tpre_descr;
 401                 stats->rx_drops_too_many_frags.value.ul =
 402                     rx_stats->rx_drops_too_many_frags;
 403                 stats->rx_drops_invalid_ring.value.ul =
 404                     rx_stats->rx_drops_invalid_ring;
 405                 stats->rx_drops_mtu.value.ul =
 406                     rx_stats->rx_drops_mtu;
 407 
 408                 stats->rx_dropped_too_small.value.ul =
 409                     port_stats->rx_dropped_too_small;
 410                 stats->rx_dropped_too_short.value.ul =
 411                     port_stats->rx_dropped_too_short;
 412                 stats->rx_dropped_header_too_small.value.ul =
 413                     port_stats->rx_dropped_header_too_small;
 414                 stats->rx_dropped_tcp_length.value.ul =
 415                     port_stats->rx_dropped_tcp_length;
 416                 stats->rx_dropped_runt.value.ul =
 417                     port_stats->rx_dropped_runt;
 418 
 419                 stats->rx_drops_no_fragments.value.ul = 0;
 420                 for (i = 0; i < dev->nrqs; i++) {
 421                         stats->rx_drops_no_fragments.value.ul +=
 422                             err_stats->rx_drops_no_fragments[dev->rq[i].rq_id];
 423                 }
 424 
 425                 stats->rx_priority_pause_frames.value.ul =
 426                     port_stats->rx_priority_pause_frames;
 427                 stats->pmem_fifo_overflow_drop.value.ul =
 428                     port_stats->pmem_fifo_overflow_drop;
 429                 stats->jabber_events.value.ul = port_stats->jabber_events;
 430                 stats->forwarded_packets.value.ul = rx_stats->forwarded_packets;
 431 
 432         }
 433 
 434         return (DDI_SUCCESS);
 435 } /* oce_update_be_stats */
 436 
 437 /*
 438  * function called by kstat to update the stats counters
 439  *
 440  * ksp - pointer to the kstats structure
 441  * rw - flags defining read/write
 442  *
 443  * return DDI_SUCCESS => success, failure otherwise
 444  */
 445 static int
 446 oce_update_stats(kstat_t *ksp, int rw)
 447 {
 448         struct oce_dev *dev;
 449         struct oce_stat *stats;
 450         int ret;
 451 
 452         if (rw == KSTAT_WRITE) {
 453                 return (EACCES);
 454         }
 455 
 456         dev = ksp->ks_private;
 457         stats = (struct oce_stat *)ksp->ks_data;
 458         mutex_enter(&dev->dev_lock);
 459         if (dev->suspended) {
 460                 mutex_exit(&dev->dev_lock);
 461                 return (EIO);
 462         }
 463         mutex_exit(&dev->dev_lock);
 464         mutex_enter(&dev->stat_lock);
 465         if (LANCER_CHIP(dev)) {
 466                 ret = oce_update_lancer_stats(dev, stats);
 467         } else {
 468                 ret = oce_update_be_stats(dev, stats);
 469         }
 470         mutex_exit(&dev->stat_lock);
 471         return (ret);
 472 } /* oce_update_stats */
 473 
 474 /*
 475  * function to setup the kstat_t structure for the device and install it
 476  *
 477  * dev - software handle to the device
 478  *
 479  * return DDI_SUCCESS => success, failure otherwise
 480  */
 481 int
 482 oce_stat_init(struct oce_dev *dev)
 483 {
 484         int ret;
 485         struct oce_stat *stats;
 486         uint32_t hw_stat_size = 0;
 487         uint32_t num_stats = sizeof (struct oce_stat) /
 488             sizeof (kstat_named_t);
 489 
 490         /* allocate the kstat */
 491         dev->oce_kstats = kstat_create(OCE_MOD_NAME, dev->dev_id, "stats",
 492             "net", KSTAT_TYPE_NAMED,
 493             num_stats, 0);
 494         if (dev->oce_kstats == NULL) {
 495                 oce_log(dev, CE_WARN, MOD_CONFIG,
 496                     "kstat creation failed: 0x%p",
 497                     (void *)dev->oce_kstats);
 498                 return (DDI_FAILURE);
 499         }
 500 
 501         if (LANCER_CHIP(dev))
 502                 hw_stat_size = sizeof (struct mbx_get_pport_stats);
 503         else
 504                 hw_stat_size = sizeof (struct mbx_get_nic_stats);
 505 
 506         /* allocate the device copy of the stats */
 507         ret = oce_alloc_dma_buffer(dev, &dev->stats_dbuf,
 508             hw_stat_size, NULL, DDI_DMA_CONSISTENT|DDI_DMA_RDWR);
 509         if (ret != DDI_SUCCESS) {
 510                 oce_log(dev, CE_WARN, MOD_CONFIG,
 511                     "Could not allocate stats_dbuf 0x%x", ret);


 512                 kstat_delete(dev->oce_kstats);
 513                 return (DDI_FAILURE);
 514         }

 515 
 516         /* initialize the counters */
 517         stats = (struct oce_stat *)dev->oce_kstats->ks_data;
 518         kstat_named_init(&stats->rx_bytes_hi, "rx bytes msd", KSTAT_DATA_ULONG);
 519         kstat_named_init(&stats->rx_bytes_lo, "rx bytes lsd", KSTAT_DATA_ULONG);
 520 
 521         kstat_named_init(&stats->rx_frames, "rx frames", KSTAT_DATA_ULONG);
 522         kstat_named_init(&stats->rx_errors, "rx errors", KSTAT_DATA_ULONG);
 523         kstat_named_init(&stats->rx_drops, "rx drops", KSTAT_DATA_ULONG);
 524 
 525         kstat_named_init(&stats->tx_bytes_hi, "tx bytes msd", KSTAT_DATA_ULONG);
 526         kstat_named_init(&stats->tx_bytes_lo, "tx bytes lsd", KSTAT_DATA_ULONG);
 527 
 528         kstat_named_init(&stats->tx_frames, "tx frames", KSTAT_DATA_ULONG);
 529         kstat_named_init(&stats->tx_errors, "tx errors", KSTAT_DATA_ULONG);
 530 
 531         kstat_named_init(&stats->rx_unicast_frames,
 532             "rx unicast frames", KSTAT_DATA_ULONG);
 533         kstat_named_init(&stats->rx_multicast_frames,
 534             "rx multicast frames", KSTAT_DATA_ULONG);


 587             "rx_drops_too_many_frags", KSTAT_DATA_ULONG);
 588         kstat_named_init(&stats->rx_drops_invalid_ring,
 589             "rx_drops_invalid_ring", KSTAT_DATA_ULONG);
 590         kstat_named_init(&stats->rx_drops_mtu,
 591             "rx_drops_mtu", KSTAT_DATA_ULONG);
 592 
 593         kstat_named_init(&stats->rx_dropped_too_small,
 594             "rx_dropped_too_small", KSTAT_DATA_ULONG);
 595         kstat_named_init(&stats->rx_dropped_too_short,
 596             "rx_dropped_too_short", KSTAT_DATA_ULONG);
 597         kstat_named_init(&stats->rx_dropped_header_too_small,
 598             "rx_dropped_header_too_small", KSTAT_DATA_ULONG);
 599         kstat_named_init(&stats->rx_dropped_tcp_length,
 600             "rx_dropped_tcp_length", KSTAT_DATA_ULONG);
 601         kstat_named_init(&stats->rx_dropped_runt,
 602             "rx_dropped_runt", KSTAT_DATA_ULONG);
 603 
 604         kstat_named_init(&stats->rx_drops_no_fragments,
 605             "rx_drop_no_frag", KSTAT_DATA_ULONG);
 606 
 607         kstat_named_init(&stats->rx_priority_pause_frames,
 608             "rx_priority_pause_frames", KSTAT_DATA_ULONG);
 609         kstat_named_init(&stats->pmem_fifo_overflow_drop,
 610             "pmem_fifo_overflow_drop", KSTAT_DATA_ULONG);
 611         kstat_named_init(&stats->jabber_events,
 612             "jabber_events", KSTAT_DATA_ULONG);
 613         kstat_named_init(&stats->forwarded_packets,
 614             "forwarded_packets", KSTAT_DATA_ULONG);
 615 
 616         dev->oce_kstats->ks_update = oce_update_stats;
 617         dev->oce_kstats->ks_private = (void *)dev;
 618         kstat_install(dev->oce_kstats);
 619 
 620         return (DDI_SUCCESS);
 621 } /* oce_stat_init */
 622 
 623 /*
 624  * function to undo initialization done in oce_stat_init
 625  *
 626  * dev - software handle to the device
 627  *
 628  * return none
 629  */
 630 void
 631 oce_stat_fini(struct oce_dev *dev)
 632 {
 633         oce_free_dma_buffer(dev, &dev->stats_dbuf);


 634         kstat_delete(dev->oce_kstats);
 635         dev->oce_kstats = NULL;
 636 } /* oce_stat_fini */
 637 
 638 /*
 639  * GLDv3 entry for statistic query
 640  */
 641 int
 642 oce_m_stat(void *arg, uint_t stat, uint64_t *val)
 643 {
 644         struct oce_dev *dev = arg;
 645         struct oce_stat *stats;
 646         int ret;
 647 
 648         stats = (struct oce_stat *)dev->oce_kstats->ks_data;


 649         mutex_enter(&dev->dev_lock);
 650 
 651         if (dev->suspended ||
 652             (dev->state & STATE_MAC_STOPPING) ||
 653             !(dev->state & STATE_MAC_STARTED)) {
 654                 mutex_exit(&dev->dev_lock);
 655                 return (EIO);
 656         }
 657         mutex_exit(&dev->dev_lock);
 658         mutex_enter(&dev->stat_lock);
 659 
 660         if (LANCER_CHIP(dev)) {
 661                 ret = oce_update_lancer_stats(dev, stats);
 662         } else {
 663                 ret = oce_update_be_stats(dev, stats);




 664         }
 665         if (ret != DDI_SUCCESS) {
 666                 mutex_exit(&dev->stat_lock);
 667                 return (EIO);
 668         }
 669         switch (stat) {
 670         case MAC_STAT_IFSPEED:
 671                 *val = dev->link_speed * 1000000ull;
 672         break;
 673 
 674         case MAC_STAT_RBYTES:


 675                 *val = (uint64_t)stats->rx_bytes_hi.value.ul << 32 |
 676                     (uint64_t)stats->rx_bytes_lo.value.ul;
 677         break;
 678 
 679         case MAC_STAT_IPACKETS:

 680                 *val = stats->rx_frames.value.ul;
 681         break;
 682 
 683         case MAC_STAT_OBYTES:


 684                 *val = (uint64_t)stats->tx_bytes_hi.value.ul << 32 |
 685                     (uint64_t)stats->tx_bytes_lo.value.ul;
 686         break;
 687 
 688         case MAC_STAT_OPACKETS:





 689                 *val = stats->tx_frames.value.ul;
 690         break;
 691 
 692         case MAC_STAT_BRDCSTRCV:


 693                 *val = stats->rx_broadcast_frames.value.ul;
 694         break;
 695 
 696         case MAC_STAT_MULTIRCV:


 697                 *val = stats->rx_multicast_frames.value.ul;
 698         break;
 699 
 700         case MAC_STAT_MULTIXMT:


 701                 *val = stats->tx_multicast_frames.value.ul;
 702         break;
 703 
 704         case MAC_STAT_BRDCSTXMT:


 705                 *val = stats->tx_broadcast_frames.value.ul;
 706         break;
 707 
 708         case MAC_STAT_NORCVBUF:


 709                 *val = stats->rx_fifo_overflow.value.ul;
 710         break;
 711 
 712         case MAC_STAT_IERRORS:








 713                 *val = stats->rx_errors.value.ul;
 714         break;
 715 
 716         case MAC_STAT_NOXMTBUF:
 717                 *val = dev->tx_noxmtbuf;
 718         break;
 719 
 720         case MAC_STAT_OERRORS:
 721                 *val = stats->tx_errors.value.ul;
 722         break;
 723 
 724         case ETHER_STAT_LINK_DUPLEX:
 725                 if (dev->state & STATE_MAC_STARTED)
 726                         *val = LINK_DUPLEX_FULL;
 727                 else
 728                         *val = LINK_DUPLEX_UNKNOWN;
 729         break;
 730 
 731         case ETHER_STAT_ALIGN_ERRORS:
 732                 *val = stats->rx_alignment_symbol_errors.value.ul;


 733         break;
 734 
 735         case ETHER_STAT_FCS_ERRORS:
 736                 *val = stats->rx_crc_errors.value.ul;


 737         break;
 738 
 739         case ETHER_STAT_MACRCV_ERRORS:









 740                 *val = stats->rx_errors.value.ul;
 741         break;
 742 
 743         case ETHER_STAT_MACXMT_ERRORS:
 744                 *val = stats->tx_errors.value.ul;
 745         break;
 746 
 747         case ETHER_STAT_TOOLONG_ERRORS:
 748                 *val = stats->rx_frame_too_long.value.ul;


 749         break;
 750 
 751         case ETHER_STAT_CAP_PAUSE:
 752         case ETHER_STAT_LINK_PAUSE:
 753                 if (dev->flow_control & OCE_FC_TX &&
 754                     dev->flow_control & OCE_FC_RX)
 755                         *val = LINK_FLOWCTRL_BI;
 756                 else if (dev->flow_control == OCE_FC_TX)
 757                         *val = LINK_FLOWCTRL_TX;
 758                 else if (dev->flow_control == OCE_FC_RX)
 759                         *val = LINK_FLOWCTRL_RX;
 760                 else if (dev->flow_control == 0)
 761                         *val = LINK_FLOWCTRL_NONE;
 762         break;
 763 
 764         default:
 765                 mutex_exit(&dev->stat_lock);
 766                 return (ENOTSUP);
 767         }
 768         mutex_exit(&dev->stat_lock);
 769         return (0);
 770 } /* oce_m_stat */