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 * Copyright 2014 QLogic Corporation 22 * The contents of this file are subject to the terms of the 23 * QLogic End User License (the "License"). 24 * You may not use this file except in compliance with the License. 25 * 26 * You can obtain a copy of the License at 27 * http://www.qlogic.com/Resources/Documents/DriverDownloadHelp/ 28 * QLogic_End_User_Software_License.txt 29 * See the License for the specific language governing permissions 30 * and limitations under the License. 31 * 32 * 33 * Module Description: 34 * 35 * 36 * History: 37 * 02/05/07 Alon Elhanani Inception. 38 ******************************************************************************/ 39 40 41 #include "lm5710.h" 42 #include "license.h" 43 #include "mcp_shmem.h" 44 #include "command.h" 45 #include "debug.h" 46 47 // does HW statistics is active 48 // only if we are PMF && collect_enabled is on! 49 #define LM_STATS_IS_HW_ACTIVE(_pdev) ( _pdev->vars.stats.stats_collect.stats_hw.b_collect_enabled && \ 50 IS_PMF(_pdev) ) 51 52 // do _cmd statement only if in SF mode 53 // we use this macro since in MF mode we don't maintain non-mandatory statistics so to prevent inconsistently - we don't use them at all 54 #define LM_STATS_DO_IF_SF(_pdev,_cmd) if( !_pdev->hw_info.mf_info.multi_vnics_mode ){ _cmd; } ; 55 56 #define LM_STATS_64_TO_HI_LO( _x_64_, _hi_lo ) ( _hi_lo##_hi = (u32_t)U64_HI( _x_64_ ) ); ( _hi_lo##_lo = (u32_t)U64_LO( _x_64_ ) ); 57 #define LM_STATS_HI_LO_TO_64( _hi_lo, _x_64_ ) ( _x_64_ = (((u64_t)(_hi_lo##_hi) << 32) | (_hi_lo##_lo)) ) 58 59 /** 60 * driver stats are stored as 64bits where the lower bits store 61 * the value and the upper bits store the wraparound count. 62 * different stat fields are stored with different data sizes 63 * and the following macros help in storing values in the 64 * "overflow count" part of a 64bit value and seperating it from 65 * the actual data. 66 */ 67 #define DATA_MASK(_bits) (((u64_t)-1)>>(64-_bits)) 68 #define STATS_DATA(_bits,_val) ( (_val) & DATA_MASK(_bits) ) 69 #define WRAPAROUND_COUNT_MASK(_bits) ( ~ DATA_MASK(_bits) ) 70 #define HAS_WRAPPED_AROUND(_bits,_old,_new) ((STATS_DATA(_bits,_old) ) > (STATS_DATA(_bits,_new) )) 71 #define INC_WRAPAROUND_COUNT(_bits,_val) (_val + ( 1ull << _bits ) ) 72 73 /**lm_update_wraparound_if_needed 74 * This function checks the old and new values, and returns a 75 * either the new data with the old wraparound count, or (if a 76 * wraparound has occured) the new data with an incremented 77 * wraparound count. 78 * 79 * val_current can be given in either little-endian or 80 * big-endian byte ordering. the values returned are always in 81 * host byte order. 82 * 83 * @param data_bits the number of data bits in the values 84 * @param val_current the newly collected value. the byte 85 * ordering is detemined by 86 * @param b_swap_bytes 87 * @param val_prev the the previously saved value in host byte 88 * order 89 * @param b_swap_bytes TRUE if val_current is byte-swapped (i.e 90 * given as little-endian on a big-endian 91 * machine), FALSE otherwise. 92 * 93 * @return u64_t the new data with an appropriate wraparound 94 * count. 95 */ 96 97 static u64_t lm_update_wraparound_if_needed(u8_t data_bits, u64_t val_current, u64_t val_prev, u8_t b_swap_bytes) 98 { 99 if(b_swap_bytes) 100 { 101 /*We assume that only 32bit stats will ever need to be byte-swapped. this is because 102 all HW data is byte-swapped by DMAE as needed, and the 64bit FW stats are swapped 103 by the REGPAIR macros.*/ 104 DbgBreakIf(data_bits != 32); 105 val_current=mm_le32_to_cpu(val_current); 106 } 107 if (HAS_WRAPPED_AROUND(data_bits,val_prev,val_current)) 108 { 109 val_prev=INC_WRAPAROUND_COUNT(data_bits,val_prev); 110 } 111 return ((val_prev & WRAPAROUND_COUNT_MASK(data_bits)) | 112 (val_current & DATA_MASK(data_bits))); /*take the overflow count we calculated, and the data from the new value*/ 113 } 114 115 /** 116 * The following macros handle the wraparound-count for FW 117 * stats. Note that in the 32bit case (i.e any stats that are 118 * not REGPAIRs), the bytes have to swapped if the host byte 119 * order is not little-endian. 120 */ 121 #define LM_SIGN_EXTEND_VALUE_32( val_current_32, val_prev_64 ) \ 122 val_prev_64 = lm_update_wraparound_if_needed( 32, val_current_32, val_prev_64, CHANGE_ENDIANITY ) 123 #define LM_SIGN_EXTEND_VALUE_36( val_current_36, val_prev_64 ) \ 124 val_prev_64 = lm_update_wraparound_if_needed( 36, val_current_36, val_prev_64, FALSE) 125 #define LM_SIGN_EXTEND_VALUE_42( val_current_42, val_prev_64 ) \ 126 val_prev_64 = lm_update_wraparound_if_needed( 42, val_current_42, val_prev_64, FALSE ) 127 128 129 130 /* function checks if there is a pending completion for statistics and a pending dpc to handle the completion: 131 * for cases where VBD gets a bit starved - we don't want to assert if chip isn't stuck and we have a pending completion 132 */ 133 u8_t is_pending_stats_completion(struct _lm_device_t * pdev); 134 135 lm_status_t lm_stats_hw_collect( struct _lm_device_t *pdev ); 136 137 #ifdef _VBD_CMD_ 138 extern volatile u32_t* g_everest_sim_flags_ptr; 139 #define EVEREST_SIM_STATS 0x02 140 #endif 141 142 143 /******************************************************************************* 144 * Description: 145 * 146 * Return: 147 ******************************************************************************/ 148 lm_status_t 149 lm_get_stats( lm_device_t* pdev, 150 lm_stats_t stats_type, 151 u64_t* stats_cnt 152 #ifdef VF_INVOLVED 153 ,lm_vf_info_t * vf_info 154 #endif 155 ) 156 { 157 lm_status_t lm_status = LM_STATUS_SUCCESS; 158 lm_u64_t* stats = (lm_u64_t *)stats_cnt; 159 const u32_t i = LM_CLI_IDX_NDIS; 160 lm_stats_fw_t* stats_fw = NULL; 161 162 #ifdef VF_INVOLVED 163 if (vf_info != NULL) { 164 stats_fw = (lm_stats_fw_t*)vf_info->vf_stats.mirror_stats_fw; 165 vf_info->vf_stats.vf_exracted_stats_cnt++; 166 } else 167 #endif 168 { 169 stats_fw = &pdev->vars.stats.stats_mirror.stats_fw; 170 } 171 172 switch(stats_type) 173 { 174 case LM_STATS_FRAMES_XMITTED_OK: 175 stats->as_u64 = stats_fw->eth_xstorm_common.client_statistics[i].total_sent_pkts ; 176 // ioc IfHCOutPkts 177 break; 178 case LM_STATS_FRAMES_RECEIVED_OK: 179 stats->as_u64 = stats_fw->eth_tstorm_common.client_statistics[i].rcv_broadcast_pkts + 180 stats_fw->eth_tstorm_common.client_statistics[i].rcv_multicast_pkts + 181 stats_fw->eth_tstorm_common.client_statistics[i].rcv_unicast_pkts ; 182 stats->as_u64-= stats_fw->eth_ustorm_common.client_statistics[i].ucast_no_buff_pkts ; 183 stats->as_u64-= stats_fw->eth_ustorm_common.client_statistics[i].mcast_no_buff_pkts ; 184 stats->as_u64-= stats_fw->eth_ustorm_common.client_statistics[i].bcast_no_buff_pkts ; 185 // ioc IfHCInPkts 186 break; 187 case LM_STATS_ERRORED_RECEIVE_CNT: 188 #ifdef VF_INVOLVED 189 DbgBreakIf(vf_info); 190 #endif 191 #define LM_STATS_ERROR_DISCARD_SUM( _pdev, _i ) _pdev->vars.stats.stats_mirror.stats_fw.eth_tstorm_common.client_statistics[_i].checksum_discard + \ 192 _pdev->vars.stats.stats_mirror.stats_fw.eth_tstorm_common.client_statistics[_i].packets_too_big_discard + \ 193 _pdev->vars.stats.stats_mirror.stats_fw.eth_tstorm_common.port_statistics.mac_discard + \ 194 LM_STATS_HW_GET_MACS_U64(_pdev, stats_rx.rx_stat_dot3statsframestoolong ) 195 stats->as_u64 = LM_STATS_ERROR_DISCARD_SUM( pdev, i ) ; 196 break; 197 case LM_STATS_RCV_CRC_ERROR: 198 // Spec. 9 199 #ifdef VF_INVOLVED 200 DbgBreakIf(vf_info); 201 #endif 202 stats->as_u64 = LM_STATS_HW_GET_MACS_U64(pdev, stats_rx.rx_stat_dot3statsfcserrors) ; 203 // ioc Dot3StatsFCSErrors 204 break; 205 case LM_STATS_ALIGNMENT_ERROR: 206 // Spec. 10 207 #ifdef VF_INVOLVED 208 DbgBreakIf(vf_info); 209 #endif 210 if( !IS_PMF(pdev)) 211 { 212 stats->as_u64 = 0 ; 213 } 214 else 215 { 216 stats->as_u64 = LM_STATS_HW_GET_MACS_U64(pdev, stats_rx.rx_stat_dot3statsalignmenterrors) ; 217 } 218 // ioc Dot3StatsAlignmentErrors 219 break; 220 case LM_STATS_SINGLE_COLLISION_FRAMES: 221 // Spec. 18 222 #ifdef VF_INVOLVED 223 DbgBreakIf(vf_info); 224 #endif 225 if( !IS_PMF(pdev) ) 226 { 227 stats->as_u64 = 0 ; 228 } 229 else 230 { 231 stats->as_u64 = LM_STATS_HW_GET_MACS_U64(pdev, stats_tx.tx_stat_dot3statssinglecollisionframes ) ; 232 } 233 // ioc Dot3StatsSingleCollisionFrames 234 break; 235 case LM_STATS_MULTIPLE_COLLISION_FRAMES: 236 // Spec. 19 237 #ifdef VF_INVOLVED 238 DbgBreakIf(vf_info); 239 #endif 240 if( !IS_PMF(pdev) ) 241 { 242 stats->as_u64 = 0 ; 243 } 244 else 245 { 246 stats->as_u64 = LM_STATS_HW_GET_MACS_U64(pdev, stats_tx.tx_stat_dot3statsmultiplecollisionframes ) ; 247 } 248 // ioc Dot3StatsMultipleCollisionFrame 249 break; 250 case LM_STATS_FRAMES_DEFERRED: 251 // Spec. 40 (not in mini port) 252 #ifdef VF_INVOLVED 253 DbgBreakIf(vf_info); 254 #endif 255 stats->as_u64 = LM_STATS_HW_GET_MACS_U64(pdev, stats_tx.tx_stat_dot3statsdeferredtransmissions ) ; 256 // ioc Dot3StatsDeferredTransmissions 257 break; 258 case LM_STATS_MAX_COLLISIONS: 259 // Spec. 21 260 #ifdef VF_INVOLVED 261 DbgBreakIf(vf_info); 262 #endif 263 stats->as_u64 = LM_STATS_HW_GET_MACS_U64(pdev, stats_tx.tx_stat_dot3statsexcessivecollisions ) ; 264 // ioc Dot3StatsExcessiveCollisions 265 break; 266 case LM_STATS_UNICAST_FRAMES_XMIT: 267 // Spec. 6 268 stats->as_u64 = stats_fw->eth_xstorm_common.client_statistics[i].unicast_pkts_sent ; 269 break; 270 case LM_STATS_MULTICAST_FRAMES_XMIT: 271 // Spec. 7 272 stats->as_u64 = stats_fw->eth_xstorm_common.client_statistics[i].multicast_pkts_sent ; 273 break; 274 case LM_STATS_BROADCAST_FRAMES_XMIT: 275 stats->as_u64 = stats_fw->eth_xstorm_common.client_statistics[i].broadcast_pkts_sent ; 276 break; 277 case LM_STATS_UNICAST_FRAMES_RCV: 278 stats->as_u64 = stats_fw->eth_tstorm_common.client_statistics[i].rcv_unicast_pkts ; 279 break; 280 case LM_STATS_MULTICAST_FRAMES_RCV: 281 stats->as_u64 = stats_fw->eth_tstorm_common.client_statistics[i].rcv_multicast_pkts ; 282 break; 283 case LM_STATS_BROADCAST_FRAMES_RCV: 284 stats->as_u64 = stats_fw->eth_tstorm_common.client_statistics[i].rcv_broadcast_pkts ; 285 break; 286 case LM_STATS_ERRORED_TRANSMIT_CNT: 287 #ifdef VF_INVOLVED 288 DbgBreakIf(vf_info); 289 #endif 290 if( !IS_PMF(pdev) ) 291 { 292 stats->as_u64 = 0 ; 293 } 294 else 295 { 296 stats->as_u64 = LM_STATS_HW_GET_MACS_U64(pdev, stats_tx.tx_stat_dot3statsinternalmactransmiterrors ) ; 297 } 298 break; 299 case LM_STATS_RCV_OVERRUN: 300 #ifdef VF_INVOLVED 301 DbgBreakIf(vf_info); 302 #endif 303 stats->as_u64 = pdev->vars.stats.stats_mirror.stats_hw.nig.brb_discard ; 304 stats->as_u64+= pdev->vars.stats.stats_mirror.stats_hw.nig.brb_truncate ; 305 stats->as_u64+= pdev->vars.stats.stats_mirror.stats_fw.eth_tstorm_common.port_statistics.xxoverflow_discard ; 306 break; 307 case LM_STATS_XMIT_UNDERRUN: 308 //These counters are always zero 309 #ifdef VF_INVOLVED 310 DbgBreakIf(vf_info); 311 #endif 312 stats->as_u64 = 0; 313 break; 314 case LM_STATS_RCV_NO_BUFFER_DROP: 315 stats->as_u64 = stats_fw->eth_tstorm_common.client_statistics[i].no_buff_discard ; 316 stats->as_u64+= stats_fw->eth_ustorm_common.client_statistics[i].ucast_no_buff_pkts ; 317 stats->as_u64+= stats_fw->eth_ustorm_common.client_statistics[i].mcast_no_buff_pkts ; 318 stats->as_u64+= stats_fw->eth_ustorm_common.client_statistics[i].bcast_no_buff_pkts ; 319 // ioc IfInMBUFDiscards 320 break; 321 case LM_STATS_BYTES_RCV: 322 stats->as_u64 = stats_fw->eth_tstorm_common.client_statistics[i].rcv_broadcast_bytes + 323 stats_fw->eth_tstorm_common.client_statistics[i].rcv_multicast_bytes + 324 stats_fw->eth_tstorm_common.client_statistics[i].rcv_unicast_bytes ; 325 // ioc IfHCInOctets 326 break; 327 case LM_STATS_BYTES_XMIT: 328 stats->as_u64 = stats_fw->eth_xstorm_common.client_statistics[i].total_sent_bytes ; 329 // ioc IfHCOutOctets 330 break; 331 case LM_STATS_IF_IN_DISCARDS: 332 #ifdef VF_INVOLVED 333 if (vf_info != NULL) 334 { 335 stats->as_u64 = 0; 336 } 337 else 338 #endif 339 { 340 stats->as_u64 = LM_STATS_ERROR_DISCARD_SUM( pdev, i ) ; // LM_STATS_ERRORED_RECEIVE_CNT 341 } 342 stats->as_u64+= stats_fw->eth_tstorm_common.client_statistics[i].no_buff_discard ; // LM_STATS_RCV_NO_BUFFER_DROP 343 stats->as_u64+= stats_fw->eth_ustorm_common.client_statistics[i].ucast_no_buff_pkts ; // LM_STATS_RCV_NO_BUFFER_DROP 344 stats->as_u64+= stats_fw->eth_ustorm_common.client_statistics[i].mcast_no_buff_pkts ; // LM_STATS_RCV_NO_BUFFER_DROP 345 stats->as_u64+= stats_fw->eth_ustorm_common.client_statistics[i].bcast_no_buff_pkts ; // LM_STATS_RCV_NO_BUFFER_DROP 346 #ifdef VF_INVOLVED 347 if (vf_info == NULL) 348 #endif 349 { 350 stats->as_u64+= pdev->vars.stats.stats_mirror.stats_hw.nig.brb_discard ; // LM_STATS_RCV_OVERRUN 351 stats->as_u64+= pdev->vars.stats.stats_mirror.stats_hw.nig.brb_truncate ; // LM_STATS_RCV_OVERRUN 352 } 353 stats->as_u64+= stats_fw->eth_tstorm_common.port_statistics.xxoverflow_discard ; // LM_STATS_RCV_OVERRUN 354 break; 355 case LM_STATS_MULTICAST_BYTES_RCV: 356 stats->as_u64 = stats_fw->eth_tstorm_common.client_statistics[i].rcv_multicast_bytes ; 357 break; 358 case LM_STATS_DIRECTED_BYTES_RCV: 359 stats->as_u64 = stats_fw->eth_tstorm_common.client_statistics[i].rcv_unicast_bytes ; 360 break; 361 case LM_STATS_BROADCAST_BYTES_RCV: 362 stats->as_u64 = stats_fw->eth_tstorm_common.client_statistics[i].rcv_broadcast_bytes ; 363 break; 364 case LM_STATS_DIRECTED_BYTES_XMIT: 365 stats->as_u64 = stats_fw->eth_xstorm_common.client_statistics[i].unicast_bytes_sent ; 366 break; 367 case LM_STATS_MULTICAST_BYTES_XMIT: 368 stats->as_u64 = stats_fw->eth_xstorm_common.client_statistics[i].multicast_bytes_sent ; 369 break; 370 case LM_STATS_BROADCAST_BYTES_XMIT: 371 stats->as_u64 = stats_fw->eth_xstorm_common.client_statistics[i].broadcast_bytes_sent ; 372 break; 373 /* 374 case LM_STATS_IF_IN_ERRORS: 375 case LM_STATS_IF_OUT_ERRORS: 376 stats->as_u32.low = 0; 377 stats->as_u32.high = 0; 378 break; 379 */ 380 default: 381 stats->as_u64 = 0 ; 382 lm_status = LM_STATUS_INVALID_PARAMETER; 383 break; 384 } 385 //DbgMessage(pdev, WARN, "lm_get_stats: stats_type=0x%X val=%d\n", stats_type, stats->as_u64); 386 return lm_status; 387 } /* lm_get_stats */ 388 /******************************************************************************* 389 * Description: 390 * Zero the mirror statistics (probably after miniport was down in windows, 'driver unload' on ediag) 391 * 392 * Return: 393 ******************************************************************************/ 394 void lm_stats_reset( struct _lm_device_t* pdev) 395 { 396 DbgMessage(pdev, INFORM, "Zero 'mirror' statistics...\n"); 397 mm_mem_zero( &pdev->vars.stats.stats_mirror, sizeof(pdev->vars.stats.stats_mirror) ) ; 398 } 399 400 /* 401 * lm_edebug_if_is_stats_disabled returns TRUE if statistics gathering is 402 * disabled according to edebug-driver interface implemented through SHMEM2 403 * field named edebug_driver_if. Otherwise, return FALSE. 404 */ 405 static u32_t 406 lm_edebug_if_is_stats_disabled(struct _lm_device_t * pdev) 407 { 408 u32_t shmem2_size; 409 u32_t offset = OFFSETOF(shmem2_region_t, edebug_driver_if[1]); 410 u32_t val; 411 412 if (pdev->hw_info.shmem_base2 != 0) 413 { 414 LM_SHMEM2_READ(pdev, OFFSETOF(shmem2_region_t, size), &shmem2_size); 415 416 if (shmem2_size > offset) 417 { 418 LM_SHMEM2_READ(pdev, offset, &val); 419 420 421 if (val == EDEBUG_DRIVER_IF_OP_CODE_DISABLE_STAT) 422 { 423 return TRUE; 424 } 425 } 426 } 427 428 return FALSE; 429 } 430 431 432 static lm_status_t lm_stats_fw_post_request(lm_device_t *pdev) 433 { 434 lm_status_t lm_status = LM_STATUS_SUCCESS; 435 lm_stats_fw_collect_t * stats_fw = &pdev->vars.stats.stats_collect.stats_fw; 436 437 stats_fw->fw_stats_req->hdr.drv_stats_counter = mm_cpu_to_le16(stats_fw->drv_counter); 438 439 // zero no completion counter 440 stats_fw->timer_wakeup_no_completion_current = 0 ; 441 442 stats_fw->b_completion_done = FALSE ; 443 if (IS_VFDEV(pdev)) 444 { 445 return LM_STATUS_SUCCESS; 446 } 447 stats_fw->b_ramrod_completed = FALSE ; 448 449 #ifdef VF_INVOLVED 450 #ifndef __LINUX 451 if (IS_CHANNEL_VIRT_MODE_MASTER_PFDEV(pdev)) 452 { 453 lm_stats_prep_vf_fw_stats_req(pdev); 454 } 455 #endif 456 #endif 457 458 /* send FW stats ramrod */ 459 lm_status = lm_sq_post_entry(pdev,&(stats_fw->stats_sp_list_command),CMD_PRIORITY_HIGH); 460 461 DbgBreakIf( LM_STATUS_SUCCESS != lm_status ) ; 462 463 if (lm_status == LM_STATUS_SUCCESS) 464 { 465 // increamant ramrod counter (for debugging) 466 ++stats_fw->stats_ramrod_cnt ; 467 } 468 469 return lm_status; 470 471 } 472 // main stats function called from timer 473 void lm_stats_on_timer( struct _lm_device_t * pdev ) 474 { 475 lm_status_t lm_status = LM_STATUS_SUCCESS ; 476 u32_t val = 0 ; 477 478 if CHK_NULL( pdev ) 479 { 480 DbgBreakIf(!pdev) ; 481 return; 482 } 483 484 ++pdev->vars.stats.stats_collect.timer_wakeup ; 485 486 #ifdef _VBD_CMD_ 487 val = GET_FLAGS(*g_everest_sim_flags_ptr, EVEREST_SIM_STATS); 488 pdev->vars.stats.stats_collect.stats_fw.b_collect_enabled = val && pdev->vars.stats.stats_collect.stats_fw.b_collect_enabled; 489 #endif 490 /* disable statistics if FW SP trace is involved */ 491 if (pdev->params.record_sp) 492 { 493 ++pdev->vars.stats.stats_collect.sp_record_disabled; 494 return; 495 } 496 /* if stats gathering is disabled according to edebug-driver i/f - return */ 497 if(lm_edebug_if_is_stats_disabled(pdev)) 498 { 499 ++pdev->vars.stats.stats_collect.shmem_disabled; 500 return; 501 } 502 503 if( pdev->vars.stats.stats_collect.stats_fw.b_collect_enabled ) 504 { 505 // verify that previous ramrod cb is finished 506 if( lm_stats_fw_complete( pdev ) == LM_STATUS_BUSY) 507 { 508 // using a variable to have event log since the message is too long 509 val = ++pdev->vars.stats.stats_collect.stats_fw.timer_wakeup_no_completion_current ; 510 511 // update timer_wakeup_no_completion_max 512 if( pdev->vars.stats.stats_collect.stats_fw.timer_wakeup_no_completion_max < val ) 513 { 514 pdev->vars.stats.stats_collect.stats_fw.timer_wakeup_no_completion_max = val ; 515 } 516 /* We give up in two case: 517 * 1. We got here #NO_COMPLETION times without having a stats-completion pending to be handled 518 * 2. There is a completion pending to be handled - but it still hasn't been handled in #COMP_NOT_HANDLED times 519 * we got here. #COMP_NOT_HANDLED > #NO_COMPLETION*/ 520 if ((!is_pending_stats_completion(pdev) && (val >= MAX_STATS_TIMER_WAKEUP_NO_COMPLETION)) || 521 (val >= MAX_STATS_TIMER_WAKEUP_COMP_NOT_HANDLED)) 522 { 523 if(GET_FLAGS(pdev->params.debug_cap_flags,DEBUG_CAP_FLAGS_STATS_FW)) 524 { 525 LM_TRIGGER_PCIE(pdev); 526 } 527 /* shutdown bug - BSOD only if shutdown is not in progress */ 528 if (!lm_reset_is_inprogress(pdev)) 529 { 530 /* BSOD */ 531 if(GET_FLAGS(pdev->params.debug_cap_flags,DEBUG_CAP_FLAGS_STATS_FW)) 532 { 533 DbgBreakIfAll( val >= MAX_STATS_TIMER_WAKEUP_NO_COMPLETION ) ; 534 } 535 } 536 } 537 538 /* check interrupt mode on 57710A0 boards */ 539 lm_57710A0_dbg_intr(pdev); 540 541 // this is total wake up no completion - for debuging 542 ++pdev->vars.stats.stats_collect.stats_fw.timer_wakeup_no_completion_total ; 543 } 544 else 545 { 546 lm_status = lm_stats_fw_post_request(pdev); 547 DbgBreakIf(lm_status != LM_STATUS_SUCCESS); 548 } 549 } // fw collect enabled 550 551 if( LM_STATS_IS_HW_ACTIVE(pdev) ) 552 { 553 // if link is not up - we can simply pass this call (optimization) 554 if( pdev->vars.stats.stats_collect.stats_hw.b_is_link_up ) 555 { 556 MM_ACQUIRE_PHY_LOCK_DPC(pdev); 557 558 // we can call dmae only if link is up, and we must check it with lock 559 if( pdev->vars.stats.stats_collect.stats_hw.b_is_link_up ) 560 { 561 lm_status = lm_stats_hw_collect( pdev ); 562 563 DbgBreakIf( LM_STATUS_SUCCESS != lm_status ) ; 564 565 // assign values for relevant mac type which is up - inside the lock due to consistecy reasons 566 lm_stats_hw_assign( pdev ) ; 567 } 568 569 // assign to statistics to MCP 570 lm_stats_mgmt_assign( pdev ) ; 571 572 MM_RELEASE_PHY_LOCK_DPC(pdev); 573 } // link is up 574 } // LM_STATS_IS_HW_ACTIVE 575 else if( pdev->vars.stats.stats_collect.stats_hw.b_collect_enabled && 576 pdev->vars.stats.stats_collect.stats_hw.b_is_link_up ) // when there is no link - no use writing to mgmt 577 { 578 MM_ACQUIRE_PHY_LOCK_DPC(pdev); 579 lm_stats_mgmt_assign( pdev ) ; 580 MM_RELEASE_PHY_LOCK_DPC(pdev); 581 } 582 } 583 584 u8_t is_pending_stats_completion(struct _lm_device_t * pdev) 585 { 586 volatile struct hc_sp_status_block * sp_sb=NULL; 587 u32_t val=0; 588 589 /* read interrupt mask from IGU - check that default-status-block bit is off... */ 590 if (INTR_BLK_TYPE(pdev)==INTR_BLK_HC){ 591 val = REG_RD(pdev, HC_REG_INT_MASK + 4*PORT_ID(pdev) ); 592 } // TODO add IGU complement 593 594 595 sp_sb = lm_get_default_status_block(pdev); 596 597 /* check bit 0 is masked (value 0) and that cstorm in default-status-block has increased. */ 598 if(!GET_FLAGS(val, 1) && lm_is_eq_completion(pdev)) 599 { 600 return TRUE; 601 } 602 return FALSE; /* no pending completion */ 603 } 604 605 /**lm_stats_get_dmae_operation 606 * The statistics module uses two pre-allocated DMAE operations 607 * instead of allocating and releasing a DMAE operation on every 608 * statistics collection. There is an operation for EMAC 609 * statistics, and an operation for BMAC or MSTAT statistics 610 * (since EMAC requires 3 SGEs and BMAC/MSTAT require 2). 611 * This function returns the appropriate DMAE operation based on 612 * current MAC setting. 613 * 614 * 615 * @param pdev the device to use. 616 * 617 * @return lm_dmae_operation_t* the DMAE operation to use for 618 * collection HW statistics from the current MAC. 619 */ 620 static lm_dmae_operation_t* 621 lm_stats_get_dmae_operation(lm_device_t* pdev) 622 { 623 if (HAS_MSTAT(pdev) || (pdev->vars.mac_type == MAC_TYPE_BMAC)) 624 { 625 return (lm_dmae_operation_t*)pdev->vars.stats.stats_collect.stats_hw.non_emac_dmae_operation; 626 } 627 else if(pdev->vars.mac_type == MAC_TYPE_EMAC) 628 { 629 return (lm_dmae_operation_t*)pdev->vars.stats.stats_collect.stats_hw.emac_dmae_operation; 630 } 631 else 632 { 633 DbgBreakIf((pdev->vars.mac_type != MAC_TYPE_EMAC) && (pdev->vars.mac_type != MAC_TYPE_BMAC)); 634 return NULL; 635 } 636 637 } 638 639 /* 640 *Function Name:lm_stats_dmae 641 * 642 *Parameters: 643 * 644 *Description: 645 * collect stats from hw using dmae 646 *Returns: 647 * 648 */ 649 lm_status_t lm_stats_dmae( lm_device_t *pdev ) 650 { 651 lm_status_t lm_status = LM_STATUS_SUCCESS ; 652 lm_dmae_context_t* context = lm_dmae_get(pdev, LM_DMAE_STATS)->context; 653 lm_dmae_operation_t* operation = lm_stats_get_dmae_operation(pdev); 654 655 DbgBreakIf( FALSE == LM_STATS_IS_HW_ACTIVE( pdev ) ) ; 656 657 if (NULL == operation) 658 { 659 DbgBreakIf( NULL == operation ); 660 return LM_STATUS_FAILURE; 661 } 662 663 lm_status = lm_dmae_context_execute(pdev,context,operation); 664 665 if (LM_STATUS_ABORTED == lm_status) 666 { 667 //if the DMAE operation was interrupted by lm_reset_is_inprogress, it's OK and we can treat it as success. 668 lm_status = LM_STATUS_SUCCESS; 669 } 670 671 return lm_status ; 672 } 673 674 /* 675 *Function Name:lm_stats_clear_emac_stats 676 * 677 *Parameters: 678 * 679 *Description: 680 * resets all emac statistics counter registers 681 *Returns: 682 * 683 */ 684 lm_status_t lm_stats_clear_emac_stats( lm_device_t *pdev ) 685 { 686 u32_t i = 0 ; 687 u32_t j = 0 ; 688 u32_t count_limit[3] = { EMAC_REG_EMAC_RX_STAT_AC_COUNT, 689 1, 690 EMAC_REG_EMAC_TX_STAT_AC_COUNT } ; 691 u32_t reg_start [3] = { EMAC_REG_EMAC_RX_STAT_AC, 692 EMAC_REG_EMAC_RX_STAT_AC_28, 693 EMAC_REG_EMAC_TX_STAT_AC } ; 694 u32_t emac_base = 0 ; 695 u32_t dummy = 0 ; 696 697 ASSERT_STATIC( ARRSIZE(reg_start) == ARRSIZE(count_limit) ); 698 699 if CHK_NULL( pdev ) 700 { 701 return LM_STATUS_INVALID_PARAMETER ; 702 } 703 704 emac_base = ( 0 == PORT_ID(pdev) ) ? GRCBASE_EMAC0 : GRCBASE_EMAC1 ; 705 706 for( i = 0; i< ARRSIZE(reg_start) ; i++ ) 707 { 708 for( j = 0 ; j < count_limit[i]; j++ ) 709 { 710 dummy = REG_RD( pdev, emac_base + reg_start[i]+(j*sizeof(u32_t))) ; /*Clear stats registers by reading from from ReadClear RX/RXerr/TX STAT banks*/ 711 } 712 } 713 return LM_STATUS_SUCCESS ; 714 } 715 716 /* 717 *Function Name:lm_stats_on_update_state 718 * 719 *Parameters: 720 * 721 *Description: 722 * This function should be called on one of two occasions: 723 * - When link is down 724 * - When PMF is going down (meaning - changed to another PMF) 725 * Function must be called under PHY LOCK 726 * 1. in case no link - do nothing 727 * 2. make last query to hw stats for current link 728 * 3. assign to mirror host structures 729 * 4. assign to MCP (managment) 730 * 5. saves the copy in mirror 731 *Returns: 732 * 733 */ 734 lm_status_t lm_stats_on_update_state(lm_device_t * pdev ) 735 { 736 lm_status_t lm_status = LM_STATUS_SUCCESS ; 737 738 if CHK_NULL( pdev ) 739 { 740 DbgBreakIf( !pdev ) ; 741 return LM_STATUS_INVALID_PARAMETER ; 742 } 743 744 if( MAC_TYPE_NONE == pdev->vars.mac_type ) 745 { 746 DbgMessage(pdev, WARNstat, "lm_stats_on_link_update: linking down when already linked down\n" ); 747 return LM_STATUS_LINK_DOWN ; 748 } 749 750 if ( LM_STATS_IS_HW_ACTIVE(pdev) ) 751 { 752 // call statistics for the last time before link down 753 lm_status = lm_stats_dmae( pdev ) ; 754 755 if( LM_STATUS_SUCCESS != lm_status ) 756 { 757 DbgBreakIf( LM_STATUS_SUCCESS != lm_status ) ; 758 } 759 760 // assign last values before link down 761 lm_stats_hw_assign( pdev ) ; 762 } 763 764 // assign to statistics to mgmt 765 lm_stats_mgmt_assign( pdev ) ; 766 767 return lm_status; 768 } 769 // NOTE: this function must be called under PHY LOCK! 770 // - 1. Lock with stats timer/dmae, whcih means - no timer request on air when function running 771 // - 2. Last update of stats from emac/bmac (TBD - do it with reset addresses) 772 // - 3. keep latest stats in a copy 773 // - 4. if emac - reset all stats registers! 774 // - 5. if up - change b_link_down_is_on flag to FALSE 775 lm_status_t lm_stats_on_link_update( lm_device_t *pdev, const u8_t b_is_link_up ) 776 { 777 lm_status_t lm_status = LM_STATUS_SUCCESS ; 778 779 if CHK_NULL( pdev ) 780 { 781 DbgBreakIf( !pdev ) ; 782 return LM_STATUS_INVALID_PARAMETER ; 783 } 784 785 if( FALSE == b_is_link_up ) // link down 786 { 787 pdev->vars.stats.stats_collect.stats_hw.b_is_link_up = FALSE ; 788 789 if ( FALSE == LM_STATS_IS_HW_ACTIVE(pdev) ) 790 { 791 return LM_STATUS_SUCCESS; 792 } 793 794 // get stats for the last time, assign to managment and save copy to mirror 795 lm_status = lm_stats_on_update_state(pdev); 796 797 if( LM_STATUS_SUCCESS != lm_status ) 798 { 799 return lm_status ; 800 } 801 802 switch( pdev->vars.mac_type ) 803 { 804 case MAC_TYPE_EMAC: 805 lm_stats_clear_emac_stats( pdev ) ; // resest emac stats fields 806 break; 807 808 case MAC_TYPE_BMAC: // nothing to do - bigmac resets itself anyway 809 break; 810 811 case MAC_TYPE_UMAC: // nothing to do - mstat resets anyway 812 case MAC_TYPE_XMAC: 813 DbgBreakIf(!CHIP_IS_E3(pdev)); 814 break; 815 816 default: 817 case MAC_TYPE_NONE: 818 DbgBreakMsg( "mac_type not acceptable\n" ) ; 819 return LM_STATUS_INVALID_PARAMETER ; 820 } 821 822 // Set current to 0 823 mm_mem_zero( &pdev->vars.stats.stats_mirror.stats_hw.macs[STATS_MACS_IDX_CURRENT], 824 sizeof(pdev->vars.stats.stats_mirror.stats_hw.macs[STATS_MACS_IDX_CURRENT]) ) ; 825 } 826 else 827 { 828 pdev->vars.stats.stats_collect.stats_hw.b_is_link_up = TRUE ; 829 } 830 831 return lm_status ; 832 } 833 834 /**lm_stats_alloc_hw_query 835 * Allocate buffers for the MAC and NIG stats. If the chip has 836 * an EMAC block, memory will be allocated for it's stats. 837 * otherwise only the non-EMAC and NIG buffers will be 838 * allocated. The non-EMAC buffer will be of the proper size for 839 * BMAC1/BMAC2/MSTAT, as needed. 840 * 841 * @param pdev the pdev to initialize 842 * 843 * @return lm_status_t LM_STATUS_SUCCESS on success, 844 * LM_STATUS_FAILURE on failure. 845 */ 846 static lm_status_t lm_stats_alloc_hw_query(lm_device_t *pdev) 847 { 848 lm_stats_hw_collect_t* stats_hw = &(pdev->vars.stats.stats_collect.stats_hw); 849 u32_t alloc_size = 0 ; 850 u32_t mac_stats_alloc_size = 0; 851 lm_address_t phys_addr = {{0}}; 852 853 if(!HAS_MSTAT(pdev)) //MSTAT replaces EMAC/BMAC1/BMAC2 stats. 854 { 855 DbgMessage(NULL, INFORM, "lm_stats_alloc_hw_query: device has no MSTAT block.\n"); 856 // Allocate continuous memory for statistics buffers to be read from hardware. This can probably be changed to 857 // allocate max(emac, bmac) instead of emac+bmac, but need to make sure there are no races in the transition from 858 // 1G link to 10G link or vice-versa 859 mac_stats_alloc_size = sizeof(struct _stats_emac_query_t) + sizeof( union _stats_bmac_query_t); 860 alloc_size = mac_stats_alloc_size + sizeof( struct _stats_nig_query_t ) ; 861 stats_hw->u.s.addr_emac_stats_query = mm_alloc_phys_mem(pdev, alloc_size, &phys_addr ,PHYS_MEM_TYPE_NONCACHED, LM_RESOURCE_COMMON ); 862 863 stats_hw->mac_stats_phys_addr = phys_addr; 864 LM_INC64(&phys_addr, sizeof(struct _stats_emac_query_t)); 865 stats_hw->bmac_stats_phys_addr = phys_addr; 866 LM_INC64(&phys_addr, sizeof( union _stats_bmac_query_t)); 867 stats_hw->nig_stats_phys_addr= phys_addr; 868 869 DbgMessage(NULL, INFORM, "lm_stats_alloc_hw_query: allocated a block of size %d at %x\n", alloc_size, stats_hw->u.s.addr_emac_stats_query); 870 if CHK_NULL( stats_hw->u.s.addr_emac_stats_query ) 871 { 872 DbgBreakIf(!stats_hw->u.s.addr_emac_stats_query ); 873 return LM_STATUS_FAILURE ; 874 } 875 876 stats_hw->u.s.addr_bmac1_stats_query = (struct _stats_bmac1_query_t*)((u8_t*)stats_hw->u.s.addr_emac_stats_query + sizeof(struct _stats_emac_query_t)) ; 877 stats_hw->u.s.addr_bmac2_stats_query = (struct _stats_bmac2_query_t*)((u8_t*)stats_hw->u.s.addr_emac_stats_query + sizeof(struct _stats_emac_query_t)) ; 878 stats_hw->addr_nig_stats_query = (struct _stats_nig_query_t*)((u8_t*)stats_hw->u.s.addr_bmac1_stats_query + sizeof(union _stats_bmac_query_t)) ; 879 DbgMessage(NULL, INFORM, "lm_stats_alloc_hw_query: addr_bmac1_stats_query = %x, addr_bmac2_stats_query=%x, addr_nig_stats_query=%x\n", stats_hw->u.s.addr_bmac1_stats_query, stats_hw->u.s.addr_bmac2_stats_query, stats_hw->addr_nig_stats_query); 880 } 881 else 882 { 883 DbgMessage(NULL, INFORM, "lm_stats_alloc_hw_query: device has an MSTAT block.\n"); 884 885 mac_stats_alloc_size = sizeof(struct _stats_mstat_query_t); 886 alloc_size = mac_stats_alloc_size + sizeof( struct _stats_nig_query_t ); 887 888 stats_hw->u.addr_mstat_stats_query = mm_alloc_phys_mem(pdev, alloc_size, &phys_addr ,PHYS_MEM_TYPE_NONCACHED, LM_RESOURCE_COMMON ); 889 890 stats_hw->mac_stats_phys_addr = phys_addr; 891 LM_INC64(&phys_addr, mac_stats_alloc_size); 892 stats_hw->nig_stats_phys_addr = phys_addr; 893 894 DbgMessage(NULL, INFORM, "lm_stats_alloc_hw_query: allocated a block of size %d at %x\n", alloc_size, stats_hw->u.addr_mstat_stats_query); 895 if CHK_NULL( stats_hw->u.addr_mstat_stats_query ) 896 { 897 DbgBreakIf(!stats_hw->u.addr_mstat_stats_query ); 898 return LM_STATUS_FAILURE ; 899 } 900 901 stats_hw->addr_nig_stats_query = (struct _stats_nig_query_t*)((u8_t*)stats_hw->u.addr_mstat_stats_query + sizeof(struct _stats_mstat_query_t)) ; 902 DbgMessage(NULL, INFORM, "lm_stats_alloc_hw_query: stats_hw->addr_nig_stats_query=%x\n", stats_hw->addr_nig_stats_query); 903 } 904 905 return LM_STATUS_SUCCESS; 906 } 907 908 lm_status_t lm_stats_alloc_fw_resc (struct _lm_device_t *pdev) 909 { 910 lm_stats_fw_collect_t * stats_fw = &pdev->vars.stats.stats_collect.stats_fw; 911 u32_t num_groups = 0; 912 u32_t alloc_size = 0; 913 u8_t num_queue_stats = 1; 914 915 /* Total number of FW statistics requests = 916 * 1 for port stats + 1 for PF stats + 1 for queue stats + 1 for FCoE stats + 1 for toe stats */ 917 #define NUM_FW_STATS_REQS 5 918 stats_fw->fw_static_stats_num = stats_fw->fw_stats_num = NUM_FW_STATS_REQS; 919 920 #ifndef __LINUX 921 if (IS_CHANNEL_VIRT_MODE_MASTER_PFDEV(pdev)) { 922 stats_fw->fw_stats_num += pdev->hw_info.sriov_info.total_vfs * 2; 923 } 924 #endif 925 926 /* Request is built from stats_query_header and an array of 927 * stats_query_cmd_group each of which contains 928 * STATS_QUERY_CMD_COUNT rules. The real number or requests is 929 * configured in the stats_query_header. 930 */ 931 num_groups = (stats_fw->fw_stats_num) / STATS_QUERY_CMD_COUNT + 932 (((stats_fw->fw_stats_num) % STATS_QUERY_CMD_COUNT) ? 1 : 0); 933 934 #ifndef __LINUX 935 if (IS_CHANNEL_VIRT_MODE_MASTER_PFDEV(pdev)) { 936 DbgMessage(pdev, WARN, "%d stats groups to support %d VFs\n",num_groups, pdev->hw_info.sriov_info.total_vfs); 937 } 938 #endif 939 stats_fw->fw_stats_req_sz = sizeof(struct stats_query_header) + 940 num_groups * sizeof(struct stats_query_cmd_group); 941 942 /* Data for statistics requests + stats_conter 943 * 944 * stats_counter holds per-STORM counters that are incremented 945 * when STORM has finished with the current request. 946 */ 947 stats_fw->fw_stats_data_sz = sizeof(struct per_port_stats) + 948 sizeof(struct per_pf_stats) + 949 sizeof(struct per_queue_stats) * num_queue_stats + 950 sizeof(struct toe_stats_query) + 951 sizeof(struct fcoe_statistics_params) + 952 sizeof(struct stats_counter); 953 954 alloc_size = stats_fw->fw_stats_data_sz + stats_fw->fw_stats_req_sz; 955 stats_fw->fw_stats = mm_alloc_phys_mem(pdev, alloc_size, &stats_fw->fw_stats_mapping ,PHYS_MEM_TYPE_NONCACHED, LM_RESOURCE_COMMON ); 956 if (!stats_fw->fw_stats) 957 { 958 return LM_STATUS_RESOURCE; 959 } 960 /* Set shortcuts */ 961 stats_fw->fw_stats_req = (lm_stats_fw_stats_req_t *)stats_fw->fw_stats; 962 stats_fw->fw_stats_req_mapping = stats_fw->fw_stats_mapping; 963 964 stats_fw->fw_stats_data = (lm_stats_fw_stats_data_t *) 965 ((u8*)stats_fw->fw_stats + stats_fw->fw_stats_req_sz); 966 967 stats_fw->fw_stats_data_mapping = stats_fw->fw_stats_mapping; 968 LM_INC64(&stats_fw->fw_stats_data_mapping, stats_fw->fw_stats_req_sz); 969 970 return LM_STATUS_SUCCESS; 971 } 972 973 /* 974 *Function Name: lm_stats_alloc_drv_info_to_mfw_resc 975 * 976 *Parameters: 977 * 978 *Description: 979 * Allocates physical memory to be used for OCBB statisics query by MFW needed for E3+ only 980 *Returns: 981 * 982 */ 983 static lm_status_t lm_stats_alloc_drv_info_to_mfw_resc(lm_device_t *pdev) 984 { 985 lm_stats_drv_info_to_mfw_t* drv_info_to_mfw = &(pdev->vars.stats.stats_collect.drv_info_to_mfw ); 986 u32_t alloc_size = 0 ; 987 lm_address_t phys_addr = {{0}}; 988 lm_status_t lm_status = LM_STATUS_SUCCESS; 989 990 if( CHIP_IS_E3(pdev) ) 991 { 992 alloc_size = max( ( sizeof( *drv_info_to_mfw->addr.eth_stats ) ), 993 ( sizeof( *drv_info_to_mfw->addr.iscsi_stats ) ) ) ; 994 alloc_size = max( ( sizeof( *drv_info_to_mfw->addr.fcoe_stats ) ), alloc_size ) ; 995 996 // since it is a union it doesn't matter 997 drv_info_to_mfw->addr.eth_stats = mm_alloc_phys_mem(pdev, alloc_size, &phys_addr ,PHYS_MEM_TYPE_NONCACHED, LM_RESOURCE_COMMON ); 998 999 if( !drv_info_to_mfw->addr.eth_stats ) 1000 { 1001 lm_status = LM_STATUS_RESOURCE; 1002 } 1003 1004 drv_info_to_mfw->drv_info_to_mfw_phys_addr = phys_addr; 1005 } 1006 1007 return lm_status; 1008 } 1009 1010 // allocate memory both for hw and fw statistics 1011 lm_status_t lm_stats_alloc_resc( struct _lm_device_t* pdev ) 1012 { 1013 u8_t loader_channel_idx = (u8_t)(-1) ; 1014 u8_t executer_channel_idx = (u8_t)(-1) ; 1015 lm_status_t lm_status = LM_STATUS_SUCCESS; 1016 lm_dmae_context_info_t *stats_dmae_context_info = lm_dmae_get(pdev, LM_DMAE_STATS); 1017 1018 if CHK_NULL(pdev ) 1019 { 1020 DbgBreakIf(!pdev) ; 1021 return LM_STATUS_INVALID_PARAMETER ; 1022 } 1023 1024 lm_status = lm_stats_alloc_fw_resc(pdev); 1025 1026 if( lm_status != LM_STATUS_SUCCESS ) 1027 { 1028 // stats is not such a big deal if not working but since we 1029 // only allocate here buffer, it doesn't matter since next alloc will also fail... 1030 return lm_status; 1031 } 1032 1033 1034 lm_status = lm_stats_alloc_drv_info_to_mfw_resc(pdev); 1035 1036 if( lm_status != LM_STATUS_SUCCESS ) 1037 { 1038 // OCBB is not such a big deal if not working but since we 1039 // only allocate here buffer, it doesn't matter since next alloc will also fail... 1040 return lm_status; 1041 } 1042 1043 lm_status = lm_stats_alloc_hw_query(pdev); 1044 if(lm_status != LM_STATUS_SUCCESS) 1045 { 1046 return lm_status; 1047 } 1048 1049 1050 switch (PORT_ID(pdev)) 1051 { 1052 case 0: 1053 { 1054 loader_channel_idx = DMAE_STATS_PORT_0_CMD_IDX_0; 1055 executer_channel_idx = DMAE_STATS_PORT_0_CMD_IDX_1; 1056 } 1057 break; 1058 case 1: 1059 { 1060 loader_channel_idx = DMAE_STATS_PORT_1_CMD_IDX_0; 1061 executer_channel_idx = DMAE_STATS_PORT_1_CMD_IDX_1; 1062 } 1063 break; 1064 default: 1065 { 1066 DbgMessage(NULL, FATAL, "Invalid Port ID %d\n", PORT_ID(pdev)); 1067 DbgBreak(); 1068 return LM_STATUS_INVALID_PARAMETER; 1069 } 1070 break; 1071 } 1072 1073 //create the locking policy for the stats DMAE context 1074 lm_status = lm_dmae_locking_policy_create(pdev, LM_PROTECTED_RESOURCE_DMAE_STATS, LM_DMAE_LOCKING_POLICY_TYPE_PER_PF, &stats_dmae_context_info->locking_policy); 1075 if(lm_status != LM_STATUS_SUCCESS) 1076 { 1077 return lm_status; 1078 } 1079 1080 //create the stats DMAE context 1081 stats_dmae_context_info->context = lm_dmae_context_create_sgl( pdev, 1082 loader_channel_idx, 1083 executer_channel_idx, 1084 &stats_dmae_context_info->locking_policy, 1085 CHANGE_ENDIANITY); 1086 if (CHK_NULL(stats_dmae_context_info->context)) 1087 { 1088 DbgBreak(); 1089 return LM_STATUS_FAILURE; 1090 } 1091 1092 //create the non-EMAC DMAE operation 1093 pdev->vars.stats.stats_collect.stats_hw.non_emac_dmae_operation = lm_dmae_operation_create_sgl(pdev, TRUE, stats_dmae_context_info->context); 1094 1095 //create the EMAC DMAE operation if needed 1096 if (!HAS_MSTAT(pdev)) 1097 { 1098 pdev->vars.stats.stats_collect.stats_hw.emac_dmae_operation = lm_dmae_operation_create_sgl(pdev, TRUE, stats_dmae_context_info->context); 1099 } 1100 else 1101 { 1102 pdev->vars.stats.stats_collect.stats_hw.emac_dmae_operation = NULL; 1103 } 1104 1105 return LM_STATUS_SUCCESS ; 1106 } 1107 1108 /**lm_stats_hw_setup_nig 1109 * Add the DMAE command for reading NIG stats to the non-EMAC 1110 * DMAE context. 1111 * 1112 * @param pdev the device to initialize 1113 * @param dmae_operation the operation to setup for reading NIG 1114 * statistics 1115 * 1116 * @return lm_status_t LM_STATUS_SUCCESS on success, some other 1117 * failure value on failure. 1118 */ 1119 static lm_status_t lm_stats_hw_setup_nig(lm_device_t* pdev, lm_dmae_operation_t* dmae_operation) 1120 { 1121 lm_status_t lm_status = LM_STATUS_FAILURE; 1122 1123 lm_dmae_address_t source = lm_dmae_address((0==PORT_ID(pdev))?NIG_REG_STAT0_BRB_DISCARD : NIG_REG_STAT1_BRB_DISCARD, 1124 LM_DMAE_ADDRESS_GRC); 1125 lm_dmae_address_t dest = lm_dmae_address(pdev->vars.stats.stats_collect.stats_hw.nig_stats_phys_addr.as_u64, 1126 LM_DMAE_ADDRESS_HOST_PHYS); 1127 1128 lm_status = lm_dmae_operation_add_sge(pdev, dmae_operation, source, dest, sizeof(struct _stats_nig_query_t ) / sizeof(u32_t)); 1129 1130 return lm_status; 1131 } 1132 1133 /** 1134 * This struct is used to describe a DMAE SGE. It is used by the 1135 * lm_status_setup_xxx and lm_stats_set_dmae_operation_sges 1136 * functions. 1137 * 1138 */ 1139 struct lm_stats_sge_descr_t{ 1140 u32_t source_offset; 1141 u64_t dest_paddr; 1142 u16_t length; // in DWORDS 1143 }; 1144 1145 1146 /**lm_stats_set_dmae_operation_sges 1147 * Set the SGEs of a DMAE operation according to the supplied 1148 * SGE descriptor array. If the DMAE operation had any SGEs 1149 * defined before, this function removes them. 1150 * 1151 * @param pdev the device to use 1152 * @param operation the operation to modify 1153 * @param sge_descr the array of SGE descriptors 1154 * @param num_sges the number of SGE descriptors 1155 * 1156 * @return lm_status_t LM_STATUS_SUCCESS on success, some other 1157 * failure value on failure. 1158 */ 1159 static lm_status_t lm_stats_set_dmae_operation_sges(lm_device_t* pdev, lm_dmae_operation_t* operation, struct lm_stats_sge_descr_t* sge_descr, u8_t num_sges) 1160 { 1161 u8_t sge_idx = 0; 1162 lm_dmae_address_t sge_source = {{0}}; 1163 lm_dmae_address_t sge_dest = {{0}}; 1164 lm_status_t lm_status = LM_STATUS_SUCCESS; 1165 1166 //after returning from D3 there may be some SGEs set up here. 1167 lm_dmae_operation_clear_all_sges(operation); 1168 1169 for (sge_idx = 0; sge_idx < num_sges; ++sge_idx) 1170 { 1171 sge_source = lm_dmae_address(sge_descr[sge_idx].source_offset, LM_DMAE_ADDRESS_GRC); 1172 sge_dest = lm_dmae_address(sge_descr[sge_idx].dest_paddr, LM_DMAE_ADDRESS_HOST_PHYS); 1173 1174 lm_status = lm_dmae_operation_add_sge(pdev, operation, sge_source, sge_dest, sge_descr[sge_idx].length); 1175 if (LM_STATUS_SUCCESS != lm_status) 1176 { 1177 DbgBreak(); 1178 return lm_status; 1179 } 1180 } 1181 1182 return lm_status; 1183 } 1184 1185 /**lm_stats_hw_setup_emac 1186 * setup the DMAE SGL for the EMAC stats DMAE context 1187 * 1188 * @param pdev the device to initialize 1189 * 1190 * @return lm_status_t LM_STATUS_SUCCESS on success, some other 1191 * value on failure. 1192 */ 1193 static lm_status_t lm_stats_hw_setup_emac( lm_device_t* pdev) 1194 { 1195 const u64_t base_paddr = pdev->vars.stats.stats_collect.stats_hw.mac_stats_phys_addr.as_u64; 1196 1197 const u16_t sge1_len = sizeof(pdev->vars.stats.stats_collect.stats_hw.u.s.addr_emac_stats_query->stats_rx ); 1198 const u16_t sge2_len = sizeof(pdev->vars.stats.stats_collect.stats_hw.u.s.addr_emac_stats_query->stats_rx_err ); 1199 const u32_t emac_base = (PORT_ID(pdev)==0) ? GRCBASE_EMAC0 : GRCBASE_EMAC1; 1200 1201 lm_status_t lm_status = LM_STATUS_FAILURE; 1202 1203 lm_dmae_operation_t* operation = pdev->vars.stats.stats_collect.stats_hw.emac_dmae_operation; 1204 1205 struct lm_stats_sge_descr_t sges[3] = {{0}}; //we can't use an initializer because DOS compiler requires that all initializers be constant. 1206 1207 sges[0].source_offset = emac_base + EMAC_REG_EMAC_RX_STAT_IFHCINOCTETS; 1208 sges[0].dest_paddr = base_paddr; 1209 sges[0].length = EMAC_REG_EMAC_RX_STAT_AC_COUNT; 1210 1211 sges[1].source_offset = emac_base + EMAC_REG_EMAC_RX_STAT_FALSECARRIERERRORS; 1212 sges[1].dest_paddr = base_paddr + sge1_len; 1213 sges[1].length = 1; 1214 1215 sges[2].source_offset = emac_base + EMAC_REG_EMAC_TX_STAT_IFHCOUTOCTETS; 1216 sges[2].dest_paddr = base_paddr + sge1_len + sge2_len; 1217 sges[2].length = EMAC_REG_EMAC_TX_STAT_AC_COUNT; 1218 1219 lm_status = lm_stats_set_dmae_operation_sges(pdev, operation, sges, ARRSIZE(sges)); 1220 if (LM_STATUS_SUCCESS != lm_status) 1221 { 1222 DbgBreakMsg("Failed to initialize EMAC stats DMAE operation.\n"); 1223 return lm_status; 1224 } 1225 1226 lm_status = lm_stats_hw_setup_nig(pdev, operation); 1227 if (LM_STATUS_SUCCESS != lm_status) 1228 { 1229 DbgBreakMsg("Failed to initialize NIG stats DMAE operation.\n"); 1230 return lm_status; 1231 } 1232 1233 return lm_status; 1234 } 1235 1236 /**lm_stats_hw_setup_non_emac 1237 * Setup the DMAE SGL for the non-EMAC stats DMAE context. This 1238 * function assumes that the MAC statistics themselves can be 1239 * read with 2 DMAE transactions. 1240 * 1241 * 1242 * @param pdev the device to initialize 1243 * @param paddr_base the base physical address where the 1244 * statistics data will be copied. 1245 * @param grc_base the base GRC address of the required stats 1246 * block (e.g NIG_REG_INGRESS_BMAC0_MEM or 1247 * GRCBASE_MSTAT0) 1248 * @param block1_start offset of the first register in the first 1249 * transaction. 1250 * @param block1_size size (in bytes) of the first DMAE 1251 * transaction. 1252 * @param block2_start offset of the first register in the 1253 * second transaction. 1254 * @param block2_size size (in bytes) of the second DMAE 1255 * transaction. 1256 * 1257 * @return lm_status_t LM_STATUS_SUCCESS on success, some other 1258 * value on failure. 1259 */ 1260 static lm_status_t lm_stats_hw_setup_non_emac( lm_device_t* pdev, 1261 u64_t paddr_base, 1262 u32_t grc_base, 1263 u32_t block1_start, u16_t block1_size, 1264 u32_t block2_start, u16_t block2_size) 1265 { 1266 lm_status_t lm_status = LM_STATUS_FAILURE; 1267 1268 lm_dmae_operation_t* operation = (lm_dmae_operation_t*)pdev->vars.stats.stats_collect.stats_hw.non_emac_dmae_operation; 1269 1270 struct lm_stats_sge_descr_t sges[2] = {{0}}; 1271 1272 sges[0].source_offset = grc_base+block1_start; 1273 sges[0].dest_paddr = paddr_base; 1274 sges[0].length = block1_size / sizeof(u32_t); 1275 1276 sges[1].source_offset = grc_base+block2_start; 1277 sges[1].dest_paddr = paddr_base + block1_size; 1278 sges[1].length = block2_size / sizeof(u32_t); 1279 1280 lm_status = lm_stats_set_dmae_operation_sges(pdev, operation, sges, ARRSIZE(sges)); 1281 if (LM_STATUS_SUCCESS != lm_status) 1282 { 1283 DbgBreakMsg("Failed to initialize non-EMAC stats DMAE operation.\n"); 1284 return lm_status; 1285 } 1286 1287 lm_status = lm_stats_hw_setup_nig(pdev, operation); 1288 if (LM_STATUS_SUCCESS != lm_status) 1289 { 1290 DbgBreakMsg("Failed to initialize NIG stats DMAE operation.\n"); 1291 return lm_status; 1292 } 1293 1294 return lm_status; 1295 } 1296 1297 /**lm_stats_hw_setup_bmac 1298 * Setup the BMAC1/BMAC2 stats DMAE transactions. 1299 * @see lm_stats_hw_setup_non_emac for more details. 1300 * 1301 * @param pdev the device to initialize. 1302 * 1303 * @return lm_status_t LM_STATUS_SUCCESS on success, some other 1304 * value on failure. 1305 */ 1306 static lm_status_t lm_stats_hw_setup_bmac(lm_device_t* pdev) 1307 { 1308 const u32_t port = PORT_ID(pdev) ; 1309 u32_t bmac_base = 0 ; // bmac: GRCBASE_NIG, bmac_base + reg name 1310 // nig :GRCBASE_NIG, reg name (NIG_XXX) 1311 u32_t bmac_tx_start_reg, bmac_rx_start_reg; 1312 u16_t bmac_tx_stat_size, bmac_rx_stat_size; 1313 lm_status_t lm_status = LM_STATUS_FAILURE; 1314 1315 DbgBreakIf(HAS_MSTAT(pdev)); 1316 1317 switch( port ) 1318 { 1319 case 0: 1320 bmac_base = NIG_REG_INGRESS_BMAC0_MEM ; 1321 break; 1322 1323 case 1: 1324 bmac_base = NIG_REG_INGRESS_BMAC1_MEM; 1325 1326 if (!CHIP_IS_E1x(pdev)) 1327 { 1328 DbgMessage(pdev, INFORMi, "BMAC stats should never be collected on port 1 of E2!\n"); 1329 bmac_base = NIG_REG_INGRESS_BMAC0_MEM; 1330 } 1331 break; 1332 1333 default: 1334 DbgBreakIf( port > 1 ) ; 1335 break; 1336 1337 } 1338 1339 if (CHIP_IS_E1x(pdev)) 1340 { 1341 bmac_tx_start_reg = BIGMAC_REGISTER_TX_STAT_GTPKT; 1342 bmac_rx_start_reg = BIGMAC_REGISTER_RX_STAT_GR64; 1343 bmac_tx_stat_size = sizeof(pdev->vars.stats.stats_collect.stats_hw.u.s.addr_bmac1_stats_query->stats_tx); 1344 bmac_rx_stat_size = sizeof(pdev->vars.stats.stats_collect.stats_hw.u.s.addr_bmac1_stats_query->stats_rx); 1345 } 1346 else 1347 { 1348 bmac_tx_start_reg = BIGMAC2_REGISTER_TX_STAT_GTPOK; 1349 bmac_rx_start_reg = BIGMAC2_REGISTER_RX_STAT_GR64; 1350 bmac_tx_stat_size = sizeof(pdev->vars.stats.stats_collect.stats_hw.u.s.addr_bmac2_stats_query->stats_tx); 1351 bmac_rx_stat_size = sizeof(pdev->vars.stats.stats_collect.stats_hw.u.s.addr_bmac2_stats_query->stats_rx); 1352 } 1353 1354 lm_status = lm_stats_hw_setup_non_emac(pdev, 1355 pdev->vars.stats.stats_collect.stats_hw.bmac_stats_phys_addr.as_u64, 1356 bmac_base, 1357 bmac_tx_start_reg, 1358 bmac_tx_stat_size, 1359 bmac_rx_start_reg, 1360 bmac_rx_stat_size); 1361 1362 return lm_status; 1363 } 1364 1365 /**lm_stats_hw_setup_mstat 1366 * Setup the MSTAT stats DMAE transactions. 1367 * @see lm_stats_hw_setup_non_emac for more details. 1368 * 1369 * @param pdev the device to initialize. 1370 * 1371 * @return lm_status_t LM_STATUS_SUCCESS on success, some other 1372 * value on failure. 1373 */ 1374 static lm_status_t lm_stats_hw_setup_mstat(lm_device_t* pdev) 1375 { 1376 const u32_t port = PORT_ID(pdev) ; 1377 u32_t mstat_base = 0; 1378 u32_t mstat_tx_start, mstat_rx_start; 1379 u16_t mstat_tx_size, mstat_rx_size; 1380 lm_status_t lm_status = LM_STATUS_FAILURE; 1381 lm_stats_hw_collect_t* stats_hw = &pdev->vars.stats.stats_collect.stats_hw; 1382 1383 DbgBreakIf(!HAS_MSTAT(pdev)); 1384 1385 mstat_tx_start = MSTAT_REG_TX_STAT_GTXPOK_LO; 1386 mstat_tx_size = sizeof(stats_hw->u.addr_mstat_stats_query->stats_tx); 1387 1388 mstat_rx_start = MSTAT_REG_RX_STAT_GR64_LO; 1389 mstat_rx_size = sizeof(stats_hw->u.addr_mstat_stats_query->stats_rx); 1390 1391 DbgMessage(pdev, INFORM, "lm_stats_hw_setup_mstat: mstat_tx_start=%x, mstat_tx_size=%x, mstat_rx_start=%x, mstat_rx_size=%x\n",mstat_tx_start,mstat_tx_size,mstat_rx_start, mstat_rx_size); 1392 1393 switch(port) 1394 { 1395 case 0: 1396 mstat_base = GRCBASE_MSTAT0; 1397 break; 1398 case 1: 1399 mstat_base = GRCBASE_MSTAT1; 1400 break; 1401 default: 1402 DbgBreakIf( port > 1 ) ; 1403 break; 1404 } 1405 1406 lm_status = lm_stats_hw_setup_non_emac(pdev, 1407 pdev->vars.stats.stats_collect.stats_hw.mac_stats_phys_addr.as_u64, 1408 mstat_base, 1409 mstat_tx_start, 1410 mstat_tx_size, 1411 mstat_rx_start, 1412 mstat_rx_size); 1413 1414 return lm_status; 1415 } 1416 1417 /* Description: 1418 * setups resources regarding hw stats (init fields) 1419 * set offsets serials of hw reads, either from EMAC & BIGMAC or from MSTAT block 1420 */ 1421 lm_status_t lm_stats_hw_setup(struct _lm_device_t *pdev) 1422 { 1423 lm_status_t lm_status = LM_STATUS_SUCCESS ; 1424 /* enable hw collect with mstat only if it's not fpga and not a 4-domain emulation compile... */ 1425 u8_t b_enable_collect = HAS_MSTAT(pdev)? ((CHIP_REV_IS_EMUL(pdev) && (CHIP_BONDING(pdev) == 0)) || CHIP_REV_IS_ASIC(pdev)) : TRUE; 1426 1427 if(HAS_MSTAT(pdev)) 1428 { 1429 lm_status = lm_stats_hw_setup_mstat(pdev); 1430 if(lm_status != LM_STATUS_SUCCESS) 1431 { 1432 DbgMessage(NULL, FATAL, "Failed to initialize MSTAT statistics\n"); 1433 return lm_status; 1434 } 1435 } 1436 else 1437 { 1438 lm_status = lm_stats_hw_setup_emac(pdev); 1439 if(lm_status != LM_STATUS_SUCCESS) 1440 { 1441 DbgMessage(NULL, FATAL, "Failed to initialize EMAC statistics\n"); 1442 return lm_status; 1443 } 1444 lm_status = lm_stats_hw_setup_bmac(pdev); 1445 if(lm_status != LM_STATUS_SUCCESS) 1446 { 1447 DbgMessage(NULL, FATAL, "Failed to initialize BMAC statistics\n"); 1448 return lm_status; 1449 } 1450 } 1451 1452 pdev->vars.stats.stats_collect.stats_hw.b_is_link_up = FALSE; 1453 1454 pdev->vars.stats.stats_collect.stats_hw.b_collect_enabled = b_enable_collect ; // HW stats are not supported on E3 FPGA. 1455 1456 return lm_status ; 1457 } /* lm_stats_hw_setup */ 1458 1459 /** 1460 * This function will prepare the statistics ramrod data the way 1461 * we will only have to increment the statistics counter and 1462 * send the ramrod each time we have to. 1463 * 1464 * @param pdev 1465 */ 1466 static void lm_stats_prep_fw_stats_req(lm_device_t *pdev) 1467 { 1468 lm_stats_fw_collect_t *stats_fw = &pdev->vars.stats.stats_collect.stats_fw; 1469 struct stats_query_header *stats_hdr = &stats_fw->fw_stats_req->hdr; 1470 lm_address_t cur_data_offset = {{0}}; 1471 struct stats_query_entry *cur_query_entry = NULL; 1472 1473 stats_hdr->cmd_num = stats_fw->fw_stats_num; 1474 stats_hdr->drv_stats_counter = 0; 1475 1476 /* storm_counters struct contains the counters of completed 1477 * statistics requests per storm which are incremented by FW 1478 * each time it completes hadning a statistics ramrod. We will 1479 * check these counters in the timer handler and discard a 1480 * (statistics) ramrod completion. 1481 */ 1482 cur_data_offset = stats_fw->fw_stats_data_mapping; 1483 LM_INC64(&cur_data_offset, OFFSETOF(lm_stats_fw_stats_data_t, storm_counters)); 1484 1485 stats_hdr->stats_counters_addrs.hi = mm_cpu_to_le32(cur_data_offset.as_u32.high); 1486 stats_hdr->stats_counters_addrs.lo = mm_cpu_to_le32(cur_data_offset.as_u32.low); 1487 1488 /* prepare to the first stats ramrod (will be completed with 1489 * the counters equal to zero) - init counters to somethig different. 1490 */ 1491 mm_memset(&stats_fw->fw_stats_data->storm_counters, 0xff, sizeof(stats_fw->fw_stats_data->storm_counters) ); 1492 1493 /**** Port FW statistics data ****/ 1494 cur_data_offset = stats_fw->fw_stats_data_mapping; 1495 LM_INC64(&cur_data_offset, OFFSETOF(lm_stats_fw_stats_data_t, port)); 1496 1497 cur_query_entry = &stats_fw->fw_stats_req->query[LM_STATS_PORT_QUERY_IDX]; 1498 1499 cur_query_entry->kind = STATS_TYPE_PORT; 1500 /* For port query index is a DONT CARE */ 1501 cur_query_entry->index = PORT_ID(pdev); 1502 cur_query_entry->funcID = mm_cpu_to_le16(FUNC_ID(pdev));; 1503 cur_query_entry->address.hi = mm_cpu_to_le32(cur_data_offset.as_u32.high); 1504 cur_query_entry->address.lo = mm_cpu_to_le32(cur_data_offset.as_u32.low); 1505 1506 /**** PF FW statistics data ****/ 1507 cur_data_offset = stats_fw->fw_stats_data_mapping; 1508 LM_INC64(&cur_data_offset, OFFSETOF(lm_stats_fw_stats_data_t, pf)); 1509 1510 cur_query_entry = &stats_fw->fw_stats_req->query[LM_STATS_PF_QUERY_IDX]; 1511 1512 cur_query_entry->kind = STATS_TYPE_PF; 1513 /* For PF query index is a DONT CARE */ 1514 cur_query_entry->index = PORT_ID(pdev); 1515 cur_query_entry->funcID = mm_cpu_to_le16(FUNC_ID(pdev)); 1516 cur_query_entry->address.hi = mm_cpu_to_le32(cur_data_offset.as_u32.high); 1517 cur_query_entry->address.lo = mm_cpu_to_le32(cur_data_offset.as_u32.low); 1518 1519 /**** Toe query ****/ 1520 cur_data_offset = stats_fw->fw_stats_data_mapping; 1521 LM_INC64(&cur_data_offset, OFFSETOF(lm_stats_fw_stats_data_t, toe)); 1522 1523 ASSERT_STATIC(LM_STATS_TOE_IDX<ARRSIZE(stats_fw->fw_stats_req->query)); 1524 cur_query_entry = &stats_fw->fw_stats_req->query[LM_STATS_TOE_IDX]; 1525 1526 cur_query_entry->kind = STATS_TYPE_TOE; 1527 cur_query_entry->index = LM_STATS_CNT_ID(pdev); 1528 cur_query_entry->funcID = mm_cpu_to_le16(FUNC_ID(pdev)); 1529 cur_query_entry->address.hi = mm_cpu_to_le32(cur_data_offset.as_u32.high); 1530 cur_query_entry->address.lo = mm_cpu_to_le32(cur_data_offset.as_u32.low); 1531 1532 if ( !CHIP_IS_E1x(pdev) ) 1533 { 1534 // FW will assert if we send this kind for chip < E2 1535 /**** FCoE query ****/ 1536 cur_data_offset = stats_fw->fw_stats_data_mapping; 1537 LM_INC64(&cur_data_offset, OFFSETOF(lm_stats_fw_stats_data_t, fcoe)); 1538 1539 ASSERT_STATIC(LM_STATS_FCOE_IDX<ARRSIZE(stats_fw->fw_stats_req->query)); 1540 cur_query_entry = &stats_fw->fw_stats_req->query[LM_STATS_FCOE_IDX]; 1541 cur_query_entry->kind = STATS_TYPE_FCOE; 1542 cur_query_entry->index = LM_STATS_CNT_ID(pdev); 1543 cur_query_entry->funcID = mm_cpu_to_le16(FUNC_ID(pdev)); 1544 cur_query_entry->address.hi = mm_cpu_to_le32(cur_data_offset.as_u32.high); 1545 cur_query_entry->address.lo = mm_cpu_to_le32(cur_data_offset.as_u32.low); 1546 } 1547 else 1548 { 1549 // if no FCoE, we need to decrease command count by one 1550 --stats_hdr->cmd_num; 1551 } 1552 1553 /**** Clients' queries ****/ 1554 cur_data_offset = stats_fw->fw_stats_data_mapping; 1555 LM_INC64(&cur_data_offset, OFFSETOF(lm_stats_fw_stats_data_t, queue_stats)); 1556 1557 ASSERT_STATIC(LM_STATS_FIRST_QUEUE_QUERY_IDX < ARRSIZE(stats_fw->fw_stats_req->query)); 1558 cur_query_entry = &stats_fw->fw_stats_req->query[LM_STATS_FIRST_QUEUE_QUERY_IDX]; 1559 1560 cur_query_entry->kind = STATS_TYPE_QUEUE; 1561 cur_query_entry->index = LM_STATS_CNT_ID(pdev); 1562 cur_query_entry->funcID = mm_cpu_to_le16(FUNC_ID(pdev)); 1563 cur_query_entry->address.hi = mm_cpu_to_le32(cur_data_offset.as_u32.high); 1564 cur_query_entry->address.lo = mm_cpu_to_le32(cur_data_offset.as_u32.low); 1565 /* TODO : VF! more stats? */ 1566 } 1567 1568 #ifdef VF_INVOLVED 1569 void lm_stats_prep_vf_fw_stats_req(lm_device_t *pdev) 1570 { 1571 lm_stats_fw_collect_t *stats_fw = &pdev->vars.stats.stats_collect.stats_fw; 1572 struct stats_query_header *stats_hdr = &stats_fw->fw_stats_req->hdr; 1573 struct stats_query_entry *cur_query_entry; 1574 u8_t vf_idx = 0; 1575 u8_t cmd_cnt = 0; 1576 lm_vf_info_t *vf_info; 1577 1578 cur_query_entry = &stats_fw->fw_stats_req->query[LM_STATS_FIRST_VF_QUEUE_QUERY_IDX]; 1579 1580 MM_ACQUIRE_VFS_STATS_LOCK_DPC(pdev); 1581 for (vf_idx = 0; vf_idx < pdev->vfs_set.number_of_enabled_vfs; vf_idx++) { 1582 vf_info = &pdev->vfs_set.vfs_array[vf_idx]; 1583 if (vf_info->vf_stats.vf_stats_state == VF_STATS_REQ_SUBMITTED) { 1584 u8_t process_it = FALSE; 1585 if (vf_info->vf_stats.vf_stats_flag & VF_STATS_COLLECT_FW_STATS_FOR_PF) { 1586 cur_query_entry->kind = STATS_TYPE_QUEUE; 1587 cur_query_entry->index = LM_FW_VF_STATS_CNT_ID(vf_info); 1588 cur_query_entry->funcID = mm_cpu_to_le16(FUNC_ID(pdev)); 1589 cur_query_entry->address.hi = mm_cpu_to_le32(vf_info->vf_stats.pf_fw_stats_phys_data.as_u32.high); 1590 cur_query_entry->address.lo = mm_cpu_to_le32(vf_info->vf_stats.pf_fw_stats_phys_data.as_u32.low); 1591 process_it = TRUE; 1592 cur_query_entry++; 1593 cmd_cnt++; 1594 } 1595 if (vf_info->vf_stats.vf_stats_flag & VF_STATS_COLLECT_FW_STATS_FOR_VF) { 1596 cur_query_entry->kind = STATS_TYPE_QUEUE; 1597 cur_query_entry->index = LM_FW_VF_STATS_CNT_ID(vf_info); 1598 cur_query_entry->funcID = mm_cpu_to_le16(8 + vf_info->abs_vf_id); 1599 cur_query_entry->address.hi = mm_cpu_to_le32(vf_info->vf_stats.vf_fw_stats_phys_data.as_u32.high); 1600 cur_query_entry->address.lo = mm_cpu_to_le32(vf_info->vf_stats.vf_fw_stats_phys_data.as_u32.low); 1601 process_it = TRUE; 1602 cur_query_entry++; 1603 cmd_cnt++; 1604 } 1605 if (process_it) { 1606 vf_info->vf_stats.vf_stats_state = VF_STATS_REQ_IN_PROCESSING; 1607 vf_info->vf_stats.vf_stats_cnt++; 1608 } 1609 } 1610 } 1611 stats_hdr->cmd_num = stats_fw->fw_static_stats_num + cmd_cnt; 1612 MM_RELEASE_VFS_STATS_LOCK_DPC(pdev); 1613 1614 } 1615 #endif 1616 1617 /* Description: 1618 * setups fw statistics parameters 1619 */ 1620 void lm_stats_fw_setup(struct _lm_device_t *pdev) 1621 { 1622 lm_stats_fw_collect_t * stats_fw = &pdev->vars.stats.stats_collect.stats_fw; 1623 stats_fw->b_completion_done = TRUE ; // reset flag to initial value 1624 stats_fw->b_ramrod_completed = TRUE ; 1625 stats_fw->drv_counter = 0 ; 1626 stats_fw->b_collect_enabled = pdev->params.fw_stats_init_value ; // change to TRUE in order to enable fw stats 1627 1628 pdev->vars.stats.stats_collect.b_last_called = TRUE ; 1629 1630 /* Prepare the constatnt slow-path command (For stats we don't allocate a new one each time) */ 1631 lm_sq_post_fill_entry(pdev, 1632 &(stats_fw->stats_sp_list_command), 1633 0 /* cid: Don't care */, 1634 RAMROD_CMD_ID_COMMON_STAT_QUERY, 1635 NONE_CONNECTION_TYPE, 1636 stats_fw->fw_stats_req_mapping.as_u64, 1637 FALSE /* don't release sp mem*/); 1638 1639 /* Prepare the FW stats ramrod request structure (can do this just once) */ 1640 lm_stats_prep_fw_stats_req(pdev); 1641 } 1642 /* 1643 *------------------------------------------------------------------------ 1644 * lm_stats_fw_check_update_done - 1645 * 1646 * check done flags and update flags 1647 * 1648 *------------------------------------------------------------------------ 1649 */ 1650 void lm_stats_fw_check_update_done( struct _lm_device_t *pdev, OUT u32_t* ptr_stats_flags_done ) 1651 { 1652 if CHK_NULL( ptr_stats_flags_done ) 1653 { 1654 DbgBreakIf(!ptr_stats_flags_done) ; 1655 return; 1656 } 1657 1658 if (IS_VFDEV(pdev)) { 1659 SET_FLAGS(*ptr_stats_flags_done,LM_STATS_FLAGS_ALL); 1660 return; 1661 } 1662 // For each storm still wasn't done, we check and if done - set, so next time 1663 // we won't need to check again 1664 1665 // eth xstorm 1666 if( 0 == GET_FLAGS(*ptr_stats_flags_done, LM_STATS_FLAG_XSTORM ) ) 1667 { 1668 if( LM_STATS_VERIFY_COUNTER( pdev, fw_stats_data->storm_counters.xstats_counter ) ) 1669 { 1670 SET_FLAGS(*ptr_stats_flags_done,LM_STATS_FLAG_XSTORM ) ; 1671 } 1672 } 1673 1674 // eth tstorm 1675 if( 0 == GET_FLAGS(*ptr_stats_flags_done, LM_STATS_FLAG_TSTORM ) ) 1676 { 1677 if( LM_STATS_VERIFY_COUNTER( pdev, fw_stats_data->storm_counters.tstats_counter ) ) 1678 { 1679 SET_FLAGS(*ptr_stats_flags_done,LM_STATS_FLAG_TSTORM ) ; 1680 } 1681 } 1682 1683 // eth ustorm 1684 if( 0 == GET_FLAGS(*ptr_stats_flags_done, LM_STATS_FLAG_USTORM ) ) 1685 { 1686 if( LM_STATS_VERIFY_COUNTER( pdev, fw_stats_data->storm_counters.ustats_counter ) ) 1687 { 1688 SET_FLAGS(*ptr_stats_flags_done,LM_STATS_FLAG_USTORM ) ; 1689 } 1690 } 1691 1692 // eth cstorm 1693 if( 0 == GET_FLAGS(*ptr_stats_flags_done, LM_STATS_FLAG_CSTORM ) ) 1694 { 1695 if( LM_STATS_VERIFY_COUNTER( pdev, fw_stats_data->storm_counters.cstats_counter ) ) 1696 { 1697 SET_FLAGS(*ptr_stats_flags_done,LM_STATS_FLAG_CSTORM ) ; 1698 } 1699 } 1700 1701 } 1702 1703 /** 1704 * @Desription: Checks if FW completed last statistic update, if 1705 * it did it assigns the statistics 1706 * 1707 * @param pdev 1708 * 1709 * @return lm_status_t LM_STATUS_SUCCESS if FW has completed 1710 * LM_STATUS_BUSY if it hasn't yet completed 1711 */ 1712 lm_status_t lm_stats_fw_complete( struct _lm_device_t *pdev ) 1713 { 1714 u32_t stats_flags_done = 0 ; // bit wise for storms done flags are on 1715 u32_t stats_flags_assigned = 0 ; // bit wise for already assigned values from storms 1716 lm_status_t lm_status = LM_STATUS_SUCCESS; 1717 1718 if CHK_NULL( pdev ) 1719 { 1720 DbgBreakIf( !pdev ) ; 1721 return LM_STATUS_INVALID_PARAMETER; 1722 } 1723 1724 /* First check if the ramrod has completed, if it hasn't don't bother checking 1725 * dma completion yet, we need both of them to complete before sending another 1726 * ramrod. */ 1727 if (IS_PFDEV(pdev) && (FALSE == pdev->vars.stats.stats_collect.stats_fw.b_ramrod_completed)) 1728 { 1729 lm_status = LM_STATUS_BUSY; 1730 } 1731 else if (FALSE == pdev->vars.stats.stats_collect.stats_fw.b_completion_done) 1732 { 1733 1734 // check done flags and update the falg if there was a change 1735 lm_stats_fw_check_update_done( pdev, &stats_flags_done ) ; 1736 1737 // Check if we can assign any of the storms 1738 if ( LM_STATS_DO_ASSIGN_ANY( stats_flags_done, stats_flags_assigned) ) 1739 { 1740 // assign stats that are ready 1741 lm_stats_fw_assign( pdev, stats_flags_done, &stats_flags_assigned ) ; 1742 #ifdef VF_INVOLVED 1743 #ifndef __LINUX 1744 if (IS_CHANNEL_VIRT_MODE_MASTER_PFDEV(pdev)) { 1745 u32_t vf_stats_flags_assigned = 0; 1746 MM_ACQUIRE_VFS_STATS_LOCK_DPC(pdev); 1747 lm_pf_stats_vf_fw_assign( pdev, stats_flags_done, &vf_stats_flags_assigned); 1748 MM_RELEASE_VFS_STATS_LOCK_DPC(pdev); 1749 } 1750 #endif 1751 #endif 1752 } 1753 1754 // did all storms were assigned 1755 if ERR_IF( LM_STATS_FLAGS_ALL != stats_flags_assigned ) 1756 { 1757 lm_status = LM_STATUS_BUSY; 1758 } 1759 else 1760 { 1761 #ifdef VF_INVOLVED 1762 #ifndef __LINUX 1763 if (IS_CHANNEL_VIRT_MODE_MASTER_PFDEV(pdev)) { 1764 u8_t vf_idx; 1765 lm_vf_info_t *vf_info; 1766 MM_ACQUIRE_VFS_STATS_LOCK_DPC(pdev); 1767 for (vf_idx = 0; vf_idx < pdev->vfs_set.number_of_enabled_vfs; vf_idx++) { 1768 vf_info = &pdev->vfs_set.vfs_array[vf_idx]; 1769 if (vf_info->vf_stats.vf_stats_state == VF_STATS_REQ_IN_PROCESSING) { 1770 if (vf_info->vf_stats.stop_collect_stats || vf_info->was_flred) { 1771 vf_info->vf_stats.vf_stats_state = VF_STATS_REQ_READY; 1772 } else { 1773 vf_info->vf_stats.vf_stats_state = VF_STATS_REQ_SUBMITTED; 1774 } 1775 } 1776 } 1777 MM_RELEASE_VFS_STATS_LOCK_DPC(pdev); 1778 } 1779 #endif 1780 #endif 1781 ++pdev->vars.stats.stats_collect.stats_fw.drv_counter ; 1782 1783 // barrier (for IA64) is to assure that the counter will be incremented BEFORE 1784 // the complation_done flag is set to TRUE. 1785 // in order to assure correct drv_counter sent to fw in lm_stats_on_timer (CQ48772) 1786 1787 if (IS_PFDEV(pdev)) 1788 { 1789 mm_write_barrier(); 1790 } 1791 // now we can notify timer that cb is done! 1792 pdev->vars.stats.stats_collect.stats_fw.b_completion_done = TRUE ; 1793 lm_status = LM_STATUS_SUCCESS; 1794 } 1795 } 1796 return lm_status; 1797 } 1798 1799 void 1800 lm_stats_fw_assign_fcoe_xstorm(IN const struct fcoe_statistics_params* collect, 1801 OUT lm_fcoe_stats_t* mirror) 1802 { 1803 //Tx 1804 LM_SIGN_EXTEND_VALUE_32(collect->tx_stat.fcoe_tx_byte_cnt, mirror->fcoe_tx_byte_cnt); 1805 LM_SIGN_EXTEND_VALUE_32(collect->tx_stat.fcoe_tx_pkt_cnt, mirror->fcoe_tx_pkt_cnt); 1806 LM_SIGN_EXTEND_VALUE_32(collect->tx_stat.fcp_tx_pkt_cnt, mirror->fcp_tx_pkt_cnt); 1807 } 1808 1809 1810 void 1811 lm_stats_fw_assign_fcoe_tstorm(IN const struct fcoe_statistics_params* collect, 1812 OUT lm_fcoe_stats_t* mirror) 1813 { 1814 //Section 0 1815 LM_SIGN_EXTEND_VALUE_32(collect->rx_stat0.fcoe_rx_byte_cnt, mirror->fcoe_rx_byte_cnt); 1816 LM_SIGN_EXTEND_VALUE_32(collect->rx_stat0.fcoe_rx_pkt_cnt, mirror->fcoe_rx_pkt_cnt); 1817 1818 //Section 1 1819 LM_SIGN_EXTEND_VALUE_32(collect->rx_stat1.fcoe_rx_drop_pkt_cnt, mirror->fcoe_rx_drop_pkt_cnt_tstorm); 1820 LM_SIGN_EXTEND_VALUE_32(collect->rx_stat1.fcoe_ver_cnt, mirror->fcoe_ver_cnt); 1821 } 1822 1823 void 1824 lm_stats_fw_assign_fcoe_ustorm(IN const struct fcoe_statistics_params* collect, 1825 OUT lm_fcoe_stats_t* mirror) 1826 { 1827 //Section 2 1828 LM_SIGN_EXTEND_VALUE_32(collect->rx_stat2.drop_seq_cnt, mirror->drop_seq_cnt); 1829 LM_SIGN_EXTEND_VALUE_32(collect->rx_stat2.eofa_del_cnt, mirror->eofa_del_cnt); 1830 LM_SIGN_EXTEND_VALUE_32(collect->rx_stat2.fc_crc_cnt, mirror->fc_crc_cnt); 1831 LM_SIGN_EXTEND_VALUE_32(collect->rx_stat2.fcoe_rx_drop_pkt_cnt, mirror->fcoe_rx_drop_pkt_cnt_ustorm); 1832 LM_SIGN_EXTEND_VALUE_32(collect->rx_stat2.fcp_rx_pkt_cnt, mirror->fcp_rx_pkt_cnt); 1833 LM_SIGN_EXTEND_VALUE_32(collect->rx_stat2.miss_frame_cnt, mirror->miss_frame_cnt); 1834 LM_SIGN_EXTEND_VALUE_32(collect->rx_stat2.seq_timeout_cnt, mirror->seq_timeout_cnt); 1835 } 1836 1837 /* 1838 *------------------------------------------------------------------------ 1839 * lm_stats_fw_assign - 1840 * 1841 * assign values from fw shared memory to the lm structs 1842 * 1843 *------------------------------------------------------------------------ 1844 */ 1845 void lm_stats_fw_assign( struct _lm_device_t *pdev, u32_t stats_flags_done, u32_t* ptr_stats_flags_assigned ) 1846 { 1847 const u8_t cli_id = LM_CLI_IDX_NDIS ; 1848 int arr_cnt = 0 ; 1849 u8_t i = 0 ; 1850 1851 if CHK_NULL( ptr_stats_flags_assigned ) 1852 { 1853 DbgBreakIf(!ptr_stats_flags_assigned) ; 1854 return; 1855 } 1856 1857 // assign reg_pair fw collected into fw mirror 1858 #define LM_STATS_FW_ASSIGN_TOE_REGPAIR(field_name) \ 1859 REGPAIR_TO_U64(pdev->vars.stats.stats_mirror.stats_fw.toe_##field_name, \ 1860 pdev->vars.stats.stats_collect.stats_fw.fw_stats_data->toe.field_name ) ; 1861 1862 // assign u32 fw collected into fw mirror + do sign extension 1863 #define LM_STATS_FW_ASSIGN_TOE_U32(field_name) \ 1864 LM_SIGN_EXTEND_VALUE_32( pdev->vars.stats.stats_collect.stats_fw.fw_stats_data->toe.field_name, \ 1865 pdev->vars.stats.stats_mirror.stats_fw.toe_##field_name ) ; 1866 1867 1868 // eth xstorm 1869 if( LM_STATS_DO_ASSIGN( stats_flags_done, *ptr_stats_flags_assigned, LM_STATS_FLAG_XSTORM ) ) 1870 { 1871 // regpairs 1872 REGPAIR_TO_U64(pdev->vars.stats.stats_mirror.stats_fw.eth_xstorm_common.client_statistics[cli_id].unicast_bytes_sent, 1873 pdev->vars.stats.stats_collect.stats_fw.fw_stats_data->queue_stats.xstorm_queue_statistics.ucast_bytes_sent); 1874 // regpairs 1875 REGPAIR_TO_U64(pdev->vars.stats.stats_mirror.stats_fw.eth_xstorm_common.client_statistics[cli_id].multicast_bytes_sent, 1876 pdev->vars.stats.stats_collect.stats_fw.fw_stats_data->queue_stats.xstorm_queue_statistics.mcast_bytes_sent); 1877 1878 // regpairs 1879 REGPAIR_TO_U64(pdev->vars.stats.stats_mirror.stats_fw.eth_xstorm_common.client_statistics[cli_id].broadcast_bytes_sent, 1880 pdev->vars.stats.stats_collect.stats_fw.fw_stats_data->queue_stats.xstorm_queue_statistics.bcast_bytes_sent); 1881 1882 pdev->vars.stats.stats_mirror.stats_fw.eth_xstorm_common.client_statistics[cli_id].total_sent_bytes = 1883 pdev->vars.stats.stats_mirror.stats_fw.eth_xstorm_common.client_statistics[cli_id].unicast_bytes_sent + 1884 pdev->vars.stats.stats_mirror.stats_fw.eth_xstorm_common.client_statistics[cli_id].multicast_bytes_sent + 1885 pdev->vars.stats.stats_mirror.stats_fw.eth_xstorm_common.client_statistics[cli_id].broadcast_bytes_sent; 1886 1887 // non regpairs 1888 LM_SIGN_EXTEND_VALUE_32( pdev->vars.stats.stats_collect.stats_fw.fw_stats_data->queue_stats.xstorm_queue_statistics.ucast_pkts_sent, 1889 pdev->vars.stats.stats_mirror.stats_fw.eth_xstorm_common.client_statistics[cli_id].unicast_pkts_sent ); 1890 1891 LM_SIGN_EXTEND_VALUE_32( pdev->vars.stats.stats_collect.stats_fw.fw_stats_data->queue_stats.xstorm_queue_statistics.mcast_pkts_sent, 1892 pdev->vars.stats.stats_mirror.stats_fw.eth_xstorm_common.client_statistics[cli_id].multicast_pkts_sent ); 1893 1894 LM_SIGN_EXTEND_VALUE_32( pdev->vars.stats.stats_collect.stats_fw.fw_stats_data->queue_stats.xstorm_queue_statistics.bcast_pkts_sent, 1895 pdev->vars.stats.stats_mirror.stats_fw.eth_xstorm_common.client_statistics[cli_id].broadcast_pkts_sent ); 1896 1897 LM_SIGN_EXTEND_VALUE_32( pdev->vars.stats.stats_collect.stats_fw.fw_stats_data->queue_stats.xstorm_queue_statistics.error_drop_pkts, 1898 pdev->vars.stats.stats_mirror.stats_fw.eth_xstorm_common.client_statistics[cli_id].error_drop_pkts ); 1899 1900 pdev->vars.stats.stats_mirror.stats_fw.eth_xstorm_common.client_statistics[cli_id].total_sent_pkts = 1901 pdev->vars.stats.stats_mirror.stats_fw.eth_xstorm_common.client_statistics[cli_id].unicast_pkts_sent+ 1902 pdev->vars.stats.stats_mirror.stats_fw.eth_xstorm_common.client_statistics[cli_id].multicast_pkts_sent + 1903 pdev->vars.stats.stats_mirror.stats_fw.eth_xstorm_common.client_statistics[cli_id].broadcast_pkts_sent; 1904 1905 1906 1907 /* TOE Stats for Xstorm */ 1908 arr_cnt = ARRSIZE(pdev->vars.stats.stats_mirror.stats_fw.toe_xstorm_toe.statistics) ; 1909 for ( i = 0; i < arr_cnt; i++) 1910 { 1911 LM_STATS_FW_ASSIGN_TOE_U32(xstorm_toe.statistics[i].tcp_out_segments) ; 1912 LM_STATS_FW_ASSIGN_TOE_U32(xstorm_toe.statistics[i].tcp_retransmitted_segments) ; 1913 LM_STATS_FW_ASSIGN_TOE_REGPAIR(xstorm_toe.statistics[i].ip_out_octets ) ; 1914 LM_STATS_FW_ASSIGN_TOE_U32(xstorm_toe.statistics[i].ip_out_requests) ; 1915 } 1916 1917 if( !CHIP_IS_E1x(pdev) ) 1918 { 1919 lm_stats_fw_assign_fcoe_xstorm(&pdev->vars.stats.stats_collect.stats_fw.fw_stats_data->fcoe, 1920 &pdev->vars.stats.stats_mirror.stats_fw.fcoe); 1921 } 1922 1923 SET_FLAGS( *ptr_stats_flags_assigned, LM_STATS_FLAG_XSTORM ) ; 1924 } 1925 1926 // eth tstorm 1927 if( LM_STATS_DO_ASSIGN( stats_flags_done, *ptr_stats_flags_assigned, LM_STATS_FLAG_TSTORM ) ) 1928 { 1929 // regpairs 1930 REGPAIR_TO_U64(pdev->vars.stats.stats_mirror.stats_fw.eth_tstorm_common.client_statistics[cli_id].rcv_unicast_bytes, 1931 pdev->vars.stats.stats_collect.stats_fw.fw_stats_data->queue_stats.tstorm_queue_statistics.rcv_ucast_bytes ); 1932 1933 REGPAIR_TO_U64(pdev->vars.stats.stats_mirror.stats_fw.eth_tstorm_common.client_statistics[cli_id].rcv_broadcast_bytes, 1934 pdev->vars.stats.stats_collect.stats_fw.fw_stats_data->queue_stats.tstorm_queue_statistics.rcv_bcast_bytes ); 1935 1936 REGPAIR_TO_U64(pdev->vars.stats.stats_mirror.stats_fw.eth_tstorm_common.client_statistics[cli_id].rcv_multicast_bytes, 1937 pdev->vars.stats.stats_collect.stats_fw.fw_stats_data->queue_stats.tstorm_queue_statistics.rcv_mcast_bytes ); 1938 1939 // FIXME REGPAIR_TO_U64(pdev->vars.stats.stats_mirror.stats_fw.eth_tstorm_common.client_statistics[cli_id].rcv_error_bytes, 1940 // pdev->vars.stats.stats_collect.stats_fw.addr_eth_stats_query->tstorm_common.client_statistics[cnt_id].rcv_error_bytes ); 1941 1942 // eth tstorm - non regpairs 1943 LM_SIGN_EXTEND_VALUE_32( pdev->vars.stats.stats_collect.stats_fw.fw_stats_data->queue_stats.tstorm_queue_statistics.checksum_discard, 1944 pdev->vars.stats.stats_mirror.stats_fw.eth_tstorm_common.client_statistics[cli_id].checksum_discard ); 1945 1946 LM_SIGN_EXTEND_VALUE_32( pdev->vars.stats.stats_collect.stats_fw.fw_stats_data->queue_stats.tstorm_queue_statistics.pkts_too_big_discard, 1947 pdev->vars.stats.stats_mirror.stats_fw.eth_tstorm_common.client_statistics[cli_id].packets_too_big_discard ); 1948 1949 LM_SIGN_EXTEND_VALUE_32( pdev->vars.stats.stats_collect.stats_fw.fw_stats_data->queue_stats.tstorm_queue_statistics.rcv_ucast_pkts, 1950 pdev->vars.stats.stats_mirror.stats_fw.eth_tstorm_common.client_statistics[cli_id].rcv_unicast_pkts ); 1951 1952 LM_SIGN_EXTEND_VALUE_32( pdev->vars.stats.stats_collect.stats_fw.fw_stats_data->queue_stats.tstorm_queue_statistics.rcv_bcast_pkts, 1953 pdev->vars.stats.stats_mirror.stats_fw.eth_tstorm_common.client_statistics[cli_id].rcv_broadcast_pkts ); 1954 1955 LM_SIGN_EXTEND_VALUE_32( pdev->vars.stats.stats_collect.stats_fw.fw_stats_data->queue_stats.tstorm_queue_statistics.rcv_mcast_pkts, 1956 pdev->vars.stats.stats_mirror.stats_fw.eth_tstorm_common.client_statistics[cli_id].rcv_multicast_pkts ); 1957 1958 LM_SIGN_EXTEND_VALUE_32( pdev->vars.stats.stats_collect.stats_fw.fw_stats_data->queue_stats.tstorm_queue_statistics.no_buff_discard, 1959 pdev->vars.stats.stats_mirror.stats_fw.eth_tstorm_common.client_statistics[cli_id].no_buff_discard ); 1960 1961 LM_SIGN_EXTEND_VALUE_32( pdev->vars.stats.stats_collect.stats_fw.fw_stats_data->queue_stats.tstorm_queue_statistics.ttl0_discard, 1962 pdev->vars.stats.stats_mirror.stats_fw.eth_tstorm_common.client_statistics[cli_id].ttl0_discard ); 1963 1964 1965 1966 LM_SIGN_EXTEND_VALUE_32( pdev->vars.stats.stats_collect.stats_fw.fw_stats_data->port.tstorm_port_statistics.mf_tag_discard, 1967 pdev->vars.stats.stats_mirror.stats_fw.eth_tstorm_common.client_statistics[cli_id].ttl0_discard ); 1968 1969 1970 /* Port Statistics */ 1971 LM_SIGN_EXTEND_VALUE_32( pdev->vars.stats.stats_collect.stats_fw.fw_stats_data->port.tstorm_port_statistics.mac_filter_discard, \ 1972 pdev->vars.stats.stats_mirror.stats_fw.eth_tstorm_common.port_statistics.mac_filter_discard ) ; 1973 LM_SIGN_EXTEND_VALUE_32( pdev->vars.stats.stats_collect.stats_fw.fw_stats_data->port.tstorm_port_statistics.brb_truncate_discard, \ 1974 pdev->vars.stats.stats_mirror.stats_fw.eth_tstorm_common.port_statistics.brb_truncate_discard ) ; 1975 LM_SIGN_EXTEND_VALUE_32( pdev->vars.stats.stats_collect.stats_fw.fw_stats_data->port.tstorm_port_statistics.mac_discard, \ 1976 pdev->vars.stats.stats_mirror.stats_fw.eth_tstorm_common.port_statistics.mac_discard ) ; 1977 1978 // toe tstorm 1979 arr_cnt = ARRSIZE(pdev->vars.stats.stats_mirror.stats_fw.toe_tstorm_toe.statistics) ; 1980 for ( i = 0; i < arr_cnt; i++) 1981 { 1982 LM_STATS_FW_ASSIGN_TOE_U32(tstorm_toe.statistics[i].ip_in_receives) ; 1983 LM_STATS_FW_ASSIGN_TOE_U32(tstorm_toe.statistics[i].ip_in_delivers) ; 1984 LM_STATS_FW_ASSIGN_TOE_REGPAIR(tstorm_toe.statistics[i].ip_in_octets) ; 1985 LM_STATS_FW_ASSIGN_TOE_U32(tstorm_toe.statistics[i].tcp_in_errors) ; 1986 LM_STATS_FW_ASSIGN_TOE_U32(tstorm_toe.statistics[i].ip_in_header_errors) ; 1987 LM_STATS_FW_ASSIGN_TOE_U32(tstorm_toe.statistics[i].ip_in_discards) ; 1988 LM_STATS_FW_ASSIGN_TOE_U32(tstorm_toe.statistics[i].ip_in_truncated_packets) ; 1989 } 1990 1991 if( !CHIP_IS_E1x(pdev) ) 1992 { 1993 lm_stats_fw_assign_fcoe_tstorm(&pdev->vars.stats.stats_collect.stats_fw.fw_stats_data->fcoe, 1994 &pdev->vars.stats.stats_mirror.stats_fw.fcoe); 1995 } 1996 1997 SET_FLAGS( *ptr_stats_flags_assigned, LM_STATS_FLAG_TSTORM ) ; 1998 } 1999 2000 // eth ustorm 2001 if( LM_STATS_DO_ASSIGN( stats_flags_done, *ptr_stats_flags_assigned, LM_STATS_FLAG_USTORM ) ) 2002 { 2003 // regpairs 2004 REGPAIR_TO_U64(pdev->vars.stats.stats_mirror.stats_fw.eth_ustorm_common.client_statistics[cli_id].ucast_no_buff_bytes, 2005 pdev->vars.stats.stats_collect.stats_fw.fw_stats_data->queue_stats.ustorm_queue_statistics.ucast_no_buff_bytes ); 2006 2007 REGPAIR_TO_U64(pdev->vars.stats.stats_mirror.stats_fw.eth_ustorm_common.client_statistics[cli_id].mcast_no_buff_bytes, 2008 pdev->vars.stats.stats_collect.stats_fw.fw_stats_data->queue_stats.ustorm_queue_statistics.mcast_no_buff_bytes ); 2009 2010 REGPAIR_TO_U64(pdev->vars.stats.stats_mirror.stats_fw.eth_ustorm_common.client_statistics[cli_id].bcast_no_buff_bytes, 2011 pdev->vars.stats.stats_collect.stats_fw.fw_stats_data->queue_stats.ustorm_queue_statistics.bcast_no_buff_bytes ); 2012 2013 REGPAIR_TO_U64(pdev->vars.stats.stats_mirror.stats_fw.eth_ustorm_common.client_statistics[cli_id].coalesced_bytes, 2014 pdev->vars.stats.stats_collect.stats_fw.fw_stats_data->queue_stats.ustorm_queue_statistics.coalesced_bytes ); 2015 2016 // non regpairs 2017 LM_SIGN_EXTEND_VALUE_32( pdev->vars.stats.stats_collect.stats_fw.fw_stats_data->queue_stats.ustorm_queue_statistics.ucast_no_buff_pkts, 2018 pdev->vars.stats.stats_mirror.stats_fw.eth_ustorm_common.client_statistics[cli_id].ucast_no_buff_pkts ); 2019 2020 LM_SIGN_EXTEND_VALUE_32( pdev->vars.stats.stats_collect.stats_fw.fw_stats_data->queue_stats.ustorm_queue_statistics.mcast_no_buff_pkts, 2021 pdev->vars.stats.stats_mirror.stats_fw.eth_ustorm_common.client_statistics[cli_id].mcast_no_buff_pkts ); 2022 2023 LM_SIGN_EXTEND_VALUE_32( pdev->vars.stats.stats_collect.stats_fw.fw_stats_data->queue_stats.ustorm_queue_statistics.bcast_no_buff_pkts, 2024 pdev->vars.stats.stats_mirror.stats_fw.eth_ustorm_common.client_statistics[cli_id].bcast_no_buff_pkts ); 2025 2026 LM_SIGN_EXTEND_VALUE_32( pdev->vars.stats.stats_collect.stats_fw.fw_stats_data->queue_stats.ustorm_queue_statistics.coalesced_pkts, 2027 pdev->vars.stats.stats_mirror.stats_fw.eth_ustorm_common.client_statistics[cli_id].coalesced_pkts ); 2028 2029 LM_SIGN_EXTEND_VALUE_32( pdev->vars.stats.stats_collect.stats_fw.fw_stats_data->queue_stats.ustorm_queue_statistics.coalesced_events, 2030 pdev->vars.stats.stats_mirror.stats_fw.eth_ustorm_common.client_statistics[cli_id].coalesced_events ); 2031 2032 LM_SIGN_EXTEND_VALUE_32( pdev->vars.stats.stats_collect.stats_fw.fw_stats_data->queue_stats.ustorm_queue_statistics.coalesced_aborts, 2033 pdev->vars.stats.stats_mirror.stats_fw.eth_ustorm_common.client_statistics[cli_id].coalesced_aborts ); 2034 2035 if( !CHIP_IS_E1x(pdev) ) 2036 { 2037 lm_stats_fw_assign_fcoe_ustorm(&pdev->vars.stats.stats_collect.stats_fw.fw_stats_data->fcoe, 2038 &pdev->vars.stats.stats_mirror.stats_fw.fcoe); 2039 } 2040 2041 SET_FLAGS( *ptr_stats_flags_assigned, LM_STATS_FLAG_USTORM ) ; 2042 } 2043 2044 if( LM_STATS_DO_ASSIGN( stats_flags_done, *ptr_stats_flags_assigned, LM_STATS_FLAG_CSTORM ) ) 2045 { 2046 // toe cstorm 2047 2048 LM_STATS_FW_ASSIGN_TOE_U32(cstorm_toe.no_tx_cqes) ; 2049 SET_FLAGS( *ptr_stats_flags_assigned, LM_STATS_FLAG_CSTORM ) ; 2050 2051 } 2052 } 2053 2054 #ifdef VF_INVOLVED 2055 void lm_pf_stats_vf_fw_assign(struct _lm_device_t *pdev, u32_t stats_flags_done, u32_t* ptr_stats_flags_assigned) 2056 { 2057 lm_stats_fw_t *mirror_stats_fw; 2058 struct per_queue_stats *queue_stats; 2059 const u8_t cli_id = LM_CLI_IDX_NDIS ; 2060 u8_t vf_idx; 2061 2062 if CHK_NULL( ptr_stats_flags_assigned ) 2063 { 2064 DbgBreakIf(!ptr_stats_flags_assigned) ; 2065 return; 2066 } 2067 2068 // eth xstorm 2069 if( LM_STATS_DO_ASSIGN( stats_flags_done, *ptr_stats_flags_assigned, LM_STATS_FLAG_XSTORM ) ) 2070 { 2071 for (vf_idx = 0; vf_idx < pdev->vfs_set.number_of_enabled_vfs; vf_idx++) { 2072 mirror_stats_fw = pdev->vfs_set.vfs_array[vf_idx].vf_stats.mirror_stats_fw; 2073 queue_stats = pdev->vfs_set.vfs_array[vf_idx].vf_stats.pf_fw_stats_virt_data; 2074 // regpairs 2075 REGPAIR_TO_U64(mirror_stats_fw->eth_xstorm_common.client_statistics[cli_id].unicast_bytes_sent, 2076 queue_stats->xstorm_queue_statistics.ucast_bytes_sent); 2077 // regpairs 2078 REGPAIR_TO_U64(mirror_stats_fw->eth_xstorm_common.client_statistics[cli_id].multicast_bytes_sent, 2079 queue_stats->xstorm_queue_statistics.mcast_bytes_sent); 2080 2081 // regpairs 2082 REGPAIR_TO_U64(mirror_stats_fw->eth_xstorm_common.client_statistics[cli_id].broadcast_bytes_sent, 2083 queue_stats->xstorm_queue_statistics.bcast_bytes_sent); 2084 2085 mirror_stats_fw->eth_xstorm_common.client_statistics[cli_id].total_sent_bytes = 2086 mirror_stats_fw->eth_xstorm_common.client_statistics[cli_id].unicast_bytes_sent + 2087 mirror_stats_fw->eth_xstorm_common.client_statistics[cli_id].multicast_bytes_sent + 2088 mirror_stats_fw->eth_xstorm_common.client_statistics[cli_id].broadcast_bytes_sent; 2089 2090 // non regpairs 2091 LM_SIGN_EXTEND_VALUE_32( queue_stats->xstorm_queue_statistics.ucast_pkts_sent, 2092 mirror_stats_fw->eth_xstorm_common.client_statistics[cli_id].unicast_pkts_sent ); 2093 2094 LM_SIGN_EXTEND_VALUE_32( queue_stats->xstorm_queue_statistics.mcast_pkts_sent, 2095 mirror_stats_fw->eth_xstorm_common.client_statistics[cli_id].multicast_pkts_sent ); 2096 2097 LM_SIGN_EXTEND_VALUE_32( queue_stats->xstorm_queue_statistics.bcast_pkts_sent, 2098 mirror_stats_fw->eth_xstorm_common.client_statistics[cli_id].broadcast_pkts_sent ); 2099 2100 mirror_stats_fw->eth_xstorm_common.client_statistics[cli_id].total_sent_pkts = 2101 mirror_stats_fw->eth_xstorm_common.client_statistics[cli_id].unicast_pkts_sent+ 2102 mirror_stats_fw->eth_xstorm_common.client_statistics[cli_id].multicast_pkts_sent + 2103 mirror_stats_fw->eth_xstorm_common.client_statistics[cli_id].broadcast_pkts_sent; 2104 2105 2106 } 2107 SET_FLAGS( *ptr_stats_flags_assigned, LM_STATS_FLAG_XSTORM ) ; 2108 } 2109 2110 // eth tstorm 2111 if( LM_STATS_DO_ASSIGN( stats_flags_done, *ptr_stats_flags_assigned, LM_STATS_FLAG_TSTORM ) ) 2112 { 2113 for (vf_idx = 0; vf_idx < pdev->vfs_set.number_of_enabled_vfs; vf_idx++) { 2114 mirror_stats_fw = pdev->vfs_set.vfs_array[vf_idx].vf_stats.mirror_stats_fw; 2115 queue_stats = pdev->vfs_set.vfs_array[vf_idx].vf_stats.pf_fw_stats_virt_data; 2116 // regpairs 2117 REGPAIR_TO_U64(mirror_stats_fw->eth_tstorm_common.client_statistics[cli_id].rcv_unicast_bytes, 2118 queue_stats->tstorm_queue_statistics.rcv_ucast_bytes ); 2119 2120 REGPAIR_TO_U64(mirror_stats_fw->eth_tstorm_common.client_statistics[cli_id].rcv_broadcast_bytes, 2121 queue_stats->tstorm_queue_statistics.rcv_bcast_bytes ); 2122 2123 REGPAIR_TO_U64(mirror_stats_fw->eth_tstorm_common.client_statistics[cli_id].rcv_multicast_bytes, 2124 queue_stats->tstorm_queue_statistics.rcv_mcast_bytes ); 2125 2126 // FIXME REGPAIR_TO_U64(pdev->vars.stats.stats_mirror.stats_fw.eth_tstorm_common.client_statistics[cli_id].rcv_error_bytes, 2127 // pdev->vars.stats.stats_collect.stats_fw.addr_eth_stats_query->tstorm_common.client_statistics[cnt_id].rcv_error_bytes ); 2128 2129 // eth tstorm - non regpairs 2130 LM_SIGN_EXTEND_VALUE_32( queue_stats->tstorm_queue_statistics.checksum_discard, 2131 mirror_stats_fw->eth_tstorm_common.client_statistics[cli_id].checksum_discard ); 2132 LM_SIGN_EXTEND_VALUE_32( queue_stats->tstorm_queue_statistics.pkts_too_big_discard, 2133 mirror_stats_fw->eth_tstorm_common.client_statistics[cli_id].packets_too_big_discard ); 2134 2135 LM_SIGN_EXTEND_VALUE_32( queue_stats->tstorm_queue_statistics.rcv_ucast_pkts, 2136 mirror_stats_fw->eth_tstorm_common.client_statistics[cli_id].rcv_unicast_pkts ); 2137 2138 LM_SIGN_EXTEND_VALUE_32( queue_stats->tstorm_queue_statistics.rcv_bcast_pkts, 2139 mirror_stats_fw->eth_tstorm_common.client_statistics[cli_id].rcv_broadcast_pkts ); 2140 2141 LM_SIGN_EXTEND_VALUE_32( queue_stats->tstorm_queue_statistics.rcv_mcast_pkts, 2142 mirror_stats_fw->eth_tstorm_common.client_statistics[cli_id].rcv_multicast_pkts ); 2143 LM_SIGN_EXTEND_VALUE_32( queue_stats->tstorm_queue_statistics.no_buff_discard, 2144 mirror_stats_fw->eth_tstorm_common.client_statistics[cli_id].no_buff_discard ); 2145 LM_SIGN_EXTEND_VALUE_32( queue_stats->tstorm_queue_statistics.ttl0_discard, 2146 mirror_stats_fw->eth_tstorm_common.client_statistics[cli_id].ttl0_discard ); 2147 2148 } 2149 SET_FLAGS( *ptr_stats_flags_assigned, LM_STATS_FLAG_TSTORM ) ; 2150 } 2151 2152 // eth ustorm 2153 if( LM_STATS_DO_ASSIGN( stats_flags_done, *ptr_stats_flags_assigned, LM_STATS_FLAG_USTORM ) ) 2154 { 2155 for (vf_idx = 0; vf_idx < pdev->vfs_set.number_of_enabled_vfs; vf_idx++) { 2156 mirror_stats_fw = pdev->vfs_set.vfs_array[vf_idx].vf_stats.mirror_stats_fw; 2157 queue_stats = pdev->vfs_set.vfs_array[vf_idx].vf_stats.pf_fw_stats_virt_data; 2158 // regpairs 2159 REGPAIR_TO_U64(mirror_stats_fw->eth_ustorm_common.client_statistics[cli_id].ucast_no_buff_bytes, 2160 queue_stats->ustorm_queue_statistics.ucast_no_buff_bytes ); 2161 2162 REGPAIR_TO_U64(mirror_stats_fw->eth_ustorm_common.client_statistics[cli_id].mcast_no_buff_bytes, 2163 queue_stats->ustorm_queue_statistics.mcast_no_buff_bytes ); 2164 2165 REGPAIR_TO_U64(mirror_stats_fw->eth_ustorm_common.client_statistics[cli_id].bcast_no_buff_bytes, 2166 queue_stats->ustorm_queue_statistics.bcast_no_buff_bytes ); 2167 2168 REGPAIR_TO_U64(pdev->vars.stats.stats_mirror.stats_fw.eth_ustorm_common.client_statistics[cli_id].coalesced_bytes, 2169 pdev->vars.stats.stats_collect.stats_fw.fw_stats_data->queue_stats.ustorm_queue_statistics.coalesced_bytes ); 2170 2171 // non regpairs 2172 LM_SIGN_EXTEND_VALUE_32( queue_stats->ustorm_queue_statistics.ucast_no_buff_pkts, 2173 mirror_stats_fw->eth_ustorm_common.client_statistics[cli_id].ucast_no_buff_pkts ); 2174 2175 LM_SIGN_EXTEND_VALUE_32( queue_stats->ustorm_queue_statistics.mcast_no_buff_pkts, 2176 mirror_stats_fw->eth_ustorm_common.client_statistics[cli_id].mcast_no_buff_pkts ); 2177 2178 LM_SIGN_EXTEND_VALUE_32( queue_stats->ustorm_queue_statistics.bcast_no_buff_pkts, 2179 mirror_stats_fw->eth_ustorm_common.client_statistics[cli_id].bcast_no_buff_pkts ); 2180 2181 LM_SIGN_EXTEND_VALUE_32( pdev->vars.stats.stats_collect.stats_fw.fw_stats_data->queue_stats.ustorm_queue_statistics.coalesced_pkts, 2182 pdev->vars.stats.stats_mirror.stats_fw.eth_ustorm_common.client_statistics[cli_id].coalesced_pkts ); 2183 2184 LM_SIGN_EXTEND_VALUE_32( pdev->vars.stats.stats_collect.stats_fw.fw_stats_data->queue_stats.ustorm_queue_statistics.coalesced_events, 2185 pdev->vars.stats.stats_mirror.stats_fw.eth_ustorm_common.client_statistics[cli_id].coalesced_events ); 2186 2187 LM_SIGN_EXTEND_VALUE_32( pdev->vars.stats.stats_collect.stats_fw.fw_stats_data->queue_stats.ustorm_queue_statistics.coalesced_aborts, 2188 pdev->vars.stats.stats_mirror.stats_fw.eth_ustorm_common.client_statistics[cli_id].coalesced_aborts ); 2189 } 2190 SET_FLAGS( *ptr_stats_flags_assigned, LM_STATS_FLAG_USTORM ) ; 2191 } 2192 2193 if( LM_STATS_DO_ASSIGN( stats_flags_done, *ptr_stats_flags_assigned, LM_STATS_FLAG_CSTORM ) ) 2194 { 2195 SET_FLAGS( *ptr_stats_flags_assigned, LM_STATS_FLAG_CSTORM ) ; 2196 } 2197 2198 } 2199 #endif 2200 2201 /**lm_stats_hw_macs_assign 2202 * 2203 * THIS FUNCTION MUST BE CALLED INSIDE PHY LOCK 2204 * 2205 * The mirrored statistics store 2 copies of the MAC stats: 2206 * CURRENT and TOTAL. the reason for this is that each PF has 2207 * it's own MAC and when a PMF change occures, the new PMF 2208 * would start with all MAC stats equal to 0. in this case 2209 * CURRENT would be zeroed on the next collection, but TOTAL 2210 * would still have the old stats. 2211 * because of this, TOTAL is updated according to the difference 2212 * between the old value and the new value. 2213 * 2214 * the following function updates a field in the CURRENT block 2215 * and returns the value to be added to the TOTAL block 2216 * 2217 * @param bits the number of data bits in the field 2218 * @param field_collect_val the value collected from the HW 2219 * @param field_mirror_val a pointer to the relevant field in 2220 * the CURRENT block 2221 * 2222 * @return the difference between the new value and the old 2223 * value - this should be added to the relevant field in 2224 * the TOTAL block. 2225 * 2226 * @see stats_macs_idx_t , lm_stats_hw_t 2227 */ 2228 static u64_t lm_stats_hw_macs_assign(IN lm_device_t* pdev, 2229 IN u8_t bits, 2230 IN u64_t field_collect_val, 2231 IN OUT u64_t *field_mirror_val) 2232 { 2233 /*MSTAT has no wraparound logic, and it's stat values are zeroed on each read. 2234 This means that what we read is the difference in the stats since the last read, 2235 so we should just update the counters and exit. 2236 EMAC and BMAC stats have wraparound logic and are not zeroed on read, so we handle 2237 the wraparound if needed and return the difference between the old value and the 2238 new value.*/ 2239 if(HAS_MSTAT(pdev)) 2240 { 2241 *field_mirror_val += field_collect_val; 2242 return field_collect_val; 2243 } 2244 else 2245 { 2246 u64_t prev = *field_mirror_val; 2247 *field_mirror_val = lm_update_wraparound_if_needed(bits, field_collect_val, *field_mirror_val,FALSE/*no need to swap bytes on HW stats*/) ; 2248 return *field_mirror_val - prev; 2249 } 2250 } 2251 2252 #define LM_STATS_HW_MAC_ASSIGN(field_collect, field_mirror, field_width)\ 2253 if (mac_query->field_collect != 0) { DbgMessage(pdev, INFORM, "assigning %s[=%x] to %s, width %d.\n", #field_collect, mac_query->field_collect, #field_mirror, field_width ); } \ 2254 macs[STATS_MACS_IDX_TOTAL].field_mirror += lm_stats_hw_macs_assign( pdev, \ 2255 field_width, \ 2256 mac_query->field_collect, \ 2257 &(macs[STATS_MACS_IDX_CURRENT].field_mirror) ) ; 2258 2259 #define LM_STATS_HW_MAC_ASSIGN_U32( field_collect, field_mirror ) LM_STATS_HW_MAC_ASSIGN(field_collect, field_mirror, 32) 2260 2261 #define LM_STATS_HW_MAC_ASSIGN_U36( field_collect, field_mirror ) LM_STATS_HW_MAC_ASSIGN(field_collect, field_mirror, 36) 2262 2263 #define LM_STATS_HW_MAC_ASSIGN_U42( field_collect, field_mirror ) LM_STATS_HW_MAC_ASSIGN(field_collect, field_mirror, 42) 2264 2265 2266 // assign a block (emac/bmac) uXX hw collected into hw mirror + do sign extension (width is XX) 2267 #define LM_STATS_HW_NIG_ASSIGN_UXX(bits, block_name,field_collect,field_mirror) \ 2268 LM_SIGN_EXTEND_VALUE_##bits( pdev->vars.stats.stats_collect.stats_hw.addr_##block_name##_stats_query->field_collect, \ 2269 pdev->vars.stats.stats_mirror.stats_hw.nig.field_mirror ) ; 2270 2271 #define LM_STATS_HW_NIG_ASSIGN_U32(block_name,field_collect,field_mirror) LM_STATS_HW_NIG_ASSIGN_UXX(32, block_name,field_collect,field_mirror) 2272 2273 2274 /* The code below is duplicated for bmac1, bmac2 and mstat, the structure mac_query differs between them and therefore 2275 * needs to be done this way (to avoid duplicating the code) */ 2276 #define LM_STATS_NON_EMAC_ASSIGN_CODE(_field_width) \ 2277 {\ 2278 /* Maps bmac_query into macs sturct */ \ 2279 /* Spec .1-5 (N/A) */ \ 2280 /* Spec .6 */ \ 2281 if (!IS_MULTI_VNIC(pdev)) { \ 2282 LM_STATS_HW_MAC_ASSIGN( stats_tx.tx_gtgca, stats_tx.tx_stat_ifhcoutucastpkts_bmac_bca, _field_width); \ 2283 LM_STATS_HW_MAC_ASSIGN( stats_tx.tx_gtgca, stats_tx.tx_stat_ifhcoutbroadcastpkts, _field_width); \ 2284 LM_STATS_HW_MAC_ASSIGN( stats_tx.tx_gtpkt, stats_tx.tx_stat_ifhcoutucastpkts_bmac_pkt , _field_width); \ 2285 LM_STATS_HW_MAC_ASSIGN( stats_tx.tx_gtmca, stats_tx.tx_stat_ifhcoutucastpkts_bmac_mca , _field_width); \ 2286 /* Spec .7 */ \ 2287 LM_STATS_HW_MAC_ASSIGN( stats_tx.tx_gtmca, stats_tx.tx_stat_ifhcoutmulticastpkts , _field_width); \ 2288 /* Spec .8 */ \ 2289 } \ 2290 /* Spec .9 */ \ 2291 LM_STATS_HW_MAC_ASSIGN( stats_rx.rx_grfcs, stats_rx.rx_stat_dot3statsfcserrors, _field_width); \ 2292 /* Spec .10-11 (N/A) */ \ 2293 /* Spec .12 */ \ 2294 /* Spec .13 */ \ 2295 LM_STATS_HW_MAC_ASSIGN( stats_rx.rx_grovr, stats_rx.rx_stat_dot3statsframestoolong, _field_width); \ 2296 /* Spec .14 (N/A) */ \ 2297 /* Spec .15 */ \ 2298 LM_STATS_HW_MAC_ASSIGN( stats_rx.rx_grxpf, stats_rx.rx_stat_xoffpauseframesreceived, _field_width); \ 2299 /* Spec .17 */ \ 2300 LM_STATS_HW_MAC_ASSIGN( stats_tx.tx_gtxpf, stats_tx.tx_stat_outxoffsent, _field_width); \ 2301 /* Spec .18-21 (N/A) */ \ 2302 /* Spec .22 */ \ 2303 LM_STATS_HW_MAC_ASSIGN( stats_rx.rx_grxpf, stats_rx.rx_stat_maccontrolframesreceived_bmac_xpf, _field_width); \ 2304 LM_STATS_HW_MAC_ASSIGN( stats_rx.rx_grxcf, stats_rx.rx_stat_maccontrolframesreceived_bmac_xcf, _field_width); \ 2305 /* Spec .23-29 (N/A) */ \ 2306 /* Spec. 30 */ \ 2307 LM_STATS_HW_MAC_ASSIGN( stats_tx.tx_gt64, stats_tx.tx_stat_etherstatspkts64octets, _field_width); \ 2308 /* Spec. 31 */ \ 2309 LM_STATS_HW_MAC_ASSIGN( stats_tx.tx_gt127, stats_tx.tx_stat_etherstatspkts65octetsto127octets, _field_width); \ 2310 /* Spec. 32 */ \ 2311 LM_STATS_HW_MAC_ASSIGN( stats_tx.tx_gt255, stats_tx.tx_stat_etherstatspkts128octetsto255octets, _field_width); \ 2312 /* Spec. 33 */ \ 2313 LM_STATS_HW_MAC_ASSIGN( stats_tx.tx_gt511, stats_tx.tx_stat_etherstatspkts256octetsto511octets, _field_width); \ 2314 /* Spec. 34 */ \ 2315 LM_STATS_HW_MAC_ASSIGN( stats_tx.tx_gt1023, stats_tx.tx_stat_etherstatspkts512octetsto1023octets, _field_width); \ 2316 /* Spec. 35 */ \ 2317 LM_STATS_HW_MAC_ASSIGN( stats_tx.tx_gt1518, stats_tx.tx_stat_etherstatspkts1024octetsto1522octet, _field_width); \ 2318 /* Spec. 36 */ \ 2319 LM_STATS_HW_MAC_ASSIGN( stats_tx.tx_gt2047, stats_tx.tx_stat_etherstatspktsover1522octets_bmac_2047, _field_width); \ 2320 LM_STATS_HW_MAC_ASSIGN( stats_tx.tx_gt4095, stats_tx.tx_stat_etherstatspktsover1522octets_bmac_4095, _field_width); \ 2321 LM_STATS_HW_MAC_ASSIGN( stats_tx.tx_gt9216, stats_tx.tx_stat_etherstatspktsover1522octets_bmac_9216, _field_width); \ 2322 LM_STATS_HW_MAC_ASSIGN( stats_tx.tx_gt16383, stats_tx.tx_stat_etherstatspktsover1522octets_bmac_16383, _field_width);\ 2323 /* Spec. 38 */ \ 2324 /* Spec. 39 */ \ 2325 /* Spec. 40 (N/A) */ \ 2326 /* Spec. 41 */ \ 2327 LM_STATS_HW_MAC_ASSIGN( stats_tx.tx_gterr, stats_tx.tx_stat_dot3statsinternalmactransmiterrors, _field_width); \ 2328 /* Spec. 42 (N/A) */ \ 2329 /* Spec. 43 */ \ 2330 LM_STATS_HW_MAC_ASSIGN( stats_tx.tx_gtxpf, stats_tx.tx_stat_flowcontroldone, _field_width); \ 2331 /* Spec. 44 */ \ 2332 LM_STATS_HW_MAC_ASSIGN( stats_rx.rx_grxpf, stats_rx.rx_stat_xoffstateentered, _field_width); \ 2333 /* Spec. 45 */ \ 2334 /* Spec. 46 (N/A) */ \ 2335 /* Spec. 47 */ \ 2336 LM_STATS_HW_MAC_ASSIGN( stats_tx.tx_gtufl, stats_tx.tx_stat_ifhcoutdiscards, _field_width); \ 2337 } 2338 2339 //Assign the registers that do not exist in MSTAT or have a different size and therefore can't 2340 //be a part of LM_STATS_NON_EMAC_ASSIGN_CODE 2341 #define LM_STATS_BMAC_ASSIGN_CODE \ 2342 { \ 2343 LM_STATS_HW_MAC_ASSIGN_U42( stats_rx.rx_grund, stats_rx.rx_stat_etherstatsundersizepkts ) ; \ 2344 LM_STATS_HW_MAC_ASSIGN_U36( stats_rx.rx_grjbr, stats_rx.rx_stat_etherstatsjabbers ) ; \ 2345 LM_STATS_HW_MAC_ASSIGN_U42( stats_rx.rx_grfrg, stats_rx.rx_stat_etherstatsfragments ) ; \ 2346 LM_STATS_HW_MAC_ASSIGN_U42( stats_rx.rx_grerb, stats_rx.rx_stat_ifhcinbadoctets ); \ 2347 } 2348 2349 /* The code below is duplicated for bmac2 and mstat, the structure mac_query differs between them and therefore 2350 * needs to be done this way (to avoid duplicating the code) */ 2351 #define LM_STATS_BMAC2_MSTAT_ASSIGN_CODE(_field_width) \ 2352 {\ 2353 LM_STATS_HW_MAC_ASSIGN( stats_tx.tx_gtxpp, stats_tx.tx_stat_pfcPacketCounter, _field_width); \ 2354 /* Rx PFC Packet Counter*/ \ 2355 LM_STATS_HW_MAC_ASSIGN( stats_rx.rx_grxpp, stats_rx.rx_stat_pfcPacketCounter, _field_width); \ 2356 } 2357 //Assign the registers that do not exist in BMAC1/BMAC2 or have a different size and therefore 2358 //can't be a part of LM_STATS_NON_EMAC_ASSIGN_CODE. 2359 //Also, some fields are read from EMAC stats on devices that have an EMAC block but must be read 2360 //from MSTAT on devices that don't have one. 2361 #define LM_STATS_MSTAT_ASSIGN_CODE \ 2362 { \ 2363 LM_STATS_HW_MAC_ASSIGN( stats_rx.rx_grund, stats_rx.rx_stat_etherstatsundersizepkts, 39) ; \ 2364 LM_STATS_HW_MAC_ASSIGN( stats_rx.rx_grfrg, stats_rx.rx_stat_etherstatsfragments, 39) ; \ 2365 LM_STATS_HW_MAC_ASSIGN( stats_rx.rx_grerb, stats_rx.rx_stat_ifhcinbadoctets, 45); \ 2366 if (!IS_MULTI_VNIC(pdev)) {\ 2367 LM_STATS_HW_MAC_ASSIGN(stats_rx.rx_grbyt, stats_rx.rx_stat_ifhcinoctets, 45);\ 2368 LM_STATS_HW_MAC_ASSIGN(stats_rx.rx_gruca, stats_rx.rx_stat_ifhcinucastpkts, 39)\ 2369 LM_STATS_HW_MAC_ASSIGN(stats_rx.rx_grmca, stats_rx.rx_stat_ifhcinmulticastpkts, 39);\ 2370 LM_STATS_HW_MAC_ASSIGN(stats_rx.rx_grbca, stats_rx.rx_stat_ifhcinbroadcastpkts, 39);\ 2371 LM_STATS_HW_MAC_ASSIGN(stats_rx.rx_gr64, stats_rx.rx_stat_etherstatspkts64octets, 39);\ 2372 LM_STATS_HW_MAC_ASSIGN(stats_rx.rx_gr127, stats_rx.rx_stat_etherstatspkts65octetsto127octets, 39);\ 2373 LM_STATS_HW_MAC_ASSIGN(stats_rx.rx_gr255, stats_rx.rx_stat_etherstatspkts128octetsto255octets, 39);\ 2374 LM_STATS_HW_MAC_ASSIGN(stats_rx.rx_gr511, stats_rx.rx_stat_etherstatspkts256octetsto511octets, 39);\ 2375 LM_STATS_HW_MAC_ASSIGN(stats_rx.rx_gr1023, stats_rx.rx_stat_etherstatspkts512octetsto1023octets, 39);\ 2376 LM_STATS_HW_MAC_ASSIGN(stats_rx.rx_gr1518, stats_rx.rx_stat_etherstatspkts1024octetsto1522octets, 39);\ 2377 LM_STATS_HW_MAC_ASSIGN(stats_rx.rx_gr2047, stats_rx.rx_stat_etherstatspktsover1522octets, 39);\ 2378 }\ 2379 } 2380 2381 /**lm_stats_hw_emac_assign 2382 * Copy the stats data from the BMAC1 stats values to the 2383 * generic struct used by the driver. This function must be 2384 * called after lm_stats_hw_collect that copies the data from 2385 * the hardware registers to the host's memory. 2386 * 2387 * 2388 * @param pdev the device to use. 2389 */ 2390 void lm_stats_hw_bmac1_assign( struct _lm_device_t *pdev) 2391 { 2392 /* Macros required for macros used in this code */ 2393 stats_macs_t *macs = &pdev->vars.stats.stats_mirror.stats_hw.macs[STATS_MACS_IDX_CURRENT]; 2394 volatile struct _stats_bmac1_query_t *mac_query = pdev->vars.stats.stats_collect.stats_hw.u.s.addr_bmac1_stats_query; 2395 2396 LM_STATS_NON_EMAC_ASSIGN_CODE(36) 2397 LM_STATS_BMAC_ASSIGN_CODE 2398 } 2399 2400 /**lm_stats_hw_emac_assign 2401 * Copy the stats data from the BMAC2 stats values to the 2402 * generic struct used by the driver. This function must be 2403 * called after lm_stats_hw_collect that copies the data from 2404 * the hardware registers to the host's memory. 2405 * 2406 * 2407 * @param pdev the device to use. 2408 */ 2409 void lm_stats_hw_bmac2_assign( struct _lm_device_t *pdev) 2410 { 2411 stats_macs_t *macs = &pdev->vars.stats.stats_mirror.stats_hw.macs[STATS_MACS_IDX_CURRENT]; 2412 volatile struct _stats_bmac2_query_t *mac_query = pdev->vars.stats.stats_collect.stats_hw.u.s.addr_bmac2_stats_query; 2413 const u8_t bmac2_field_width = 36; 2414 2415 DbgBreakIf(mac_query == NULL); 2416 2417 LM_STATS_NON_EMAC_ASSIGN_CODE(bmac2_field_width) 2418 LM_STATS_BMAC2_MSTAT_ASSIGN_CODE(bmac2_field_width) 2419 LM_STATS_BMAC_ASSIGN_CODE 2420 } 2421 2422 /**lm_stats_hw_emac_assign 2423 * Copy the stats data from the MSTAT stats values to the 2424 * generic struct used by the driver. This function must be 2425 * called after lm_stats_hw_collect that copies the data from 2426 * the hardware registers to the host's memory. 2427 * 2428 * 2429 * @param pdev the device to use. 2430 */ 2431 void lm_stats_hw_mstat_assign( lm_device_t* pdev) 2432 { 2433 stats_macs_t *macs = &pdev->vars.stats.stats_mirror.stats_hw.macs[STATS_MACS_IDX_CURRENT]; 2434 volatile struct _stats_mstat_query_t *mac_query = pdev->vars.stats.stats_collect.stats_hw.u.addr_mstat_stats_query; 2435 const u8_t mstat_field_width = 39; 2436 DbgBreakIf(mac_query == NULL); 2437 2438 DbgMessage(pdev, INFORM, "lm_stats_hw_mstat_assign: mac_query=%x\n", mac_query); 2439 2440 LM_STATS_NON_EMAC_ASSIGN_CODE(mstat_field_width) 2441 LM_STATS_BMAC2_MSTAT_ASSIGN_CODE(mstat_field_width) 2442 LM_STATS_MSTAT_ASSIGN_CODE 2443 } 2444 2445 /**lm_stats_hw_emac_assign 2446 * Copy the stats data from the EMAC stats values to the generic 2447 * struct used by the driver. This function must be called after 2448 * lm_stats_hw_collect that copies the data from the hardware 2449 * registers to the host's memory. 2450 * 2451 * 2452 * @param pdev the device to use. 2453 */ 2454 void lm_stats_hw_emac_assign( struct _lm_device_t *pdev) 2455 { 2456 stats_macs_t *macs = &pdev->vars.stats.stats_mirror.stats_hw.macs[STATS_MACS_IDX_CURRENT]; 2457 volatile struct _stats_emac_query_t *mac_query = pdev->vars.stats.stats_collect.stats_hw.u.s.addr_emac_stats_query; 2458 2459 DbgBreakIf(mac_query == NULL); 2460 2461 LM_STATS_HW_MAC_ASSIGN_U32(stats_rx.rx_stat_ifhcinbadoctets, stats_rx.rx_stat_ifhcinbadoctets ) ; 2462 LM_STATS_HW_MAC_ASSIGN_U32(stats_rx.rx_stat_etherstatsfragments, stats_rx.rx_stat_etherstatsfragments ) ; 2463 2464 if (!IS_MULTI_VNIC(pdev)) { 2465 LM_STATS_HW_MAC_ASSIGN_U32(stats_rx.rx_stat_ifhcinoctets, stats_rx.rx_stat_ifhcinoctets ); 2466 LM_STATS_HW_MAC_ASSIGN_U32(stats_rx.rx_stat_ifhcinucastpkts, stats_rx.rx_stat_ifhcinucastpkts ) 2467 LM_STATS_HW_MAC_ASSIGN_U32(stats_rx.rx_stat_ifhcinmulticastpkts, stats_rx.rx_stat_ifhcinmulticastpkts ); 2468 LM_STATS_HW_MAC_ASSIGN_U32(stats_rx.rx_stat_ifhcinbroadcastpkts, stats_rx.rx_stat_ifhcinbroadcastpkts ); 2469 LM_STATS_HW_MAC_ASSIGN_U32(stats_rx.rx_stat_etherstatspkts64octets, stats_rx.rx_stat_etherstatspkts64octets ); 2470 LM_STATS_HW_MAC_ASSIGN_U32(stats_rx.rx_stat_etherstatspkts65octetsto127octets, stats_rx.rx_stat_etherstatspkts65octetsto127octets ); 2471 LM_STATS_HW_MAC_ASSIGN_U32(stats_rx.rx_stat_etherstatspkts128octetsto255octets, stats_rx.rx_stat_etherstatspkts128octetsto255octets ); 2472 LM_STATS_HW_MAC_ASSIGN_U32(stats_rx.rx_stat_etherstatspkts256octetsto511octets, stats_rx.rx_stat_etherstatspkts256octetsto511octets ); 2473 LM_STATS_HW_MAC_ASSIGN_U32(stats_rx.rx_stat_etherstatspkts512octetsto1023octets, stats_rx.rx_stat_etherstatspkts512octetsto1023octets); 2474 LM_STATS_HW_MAC_ASSIGN_U32(stats_rx.rx_stat_etherstatspkts1024octetsto1522octets, stats_rx.rx_stat_etherstatspkts1024octetsto1522octets); 2475 LM_STATS_HW_MAC_ASSIGN_U32(stats_rx.rx_stat_etherstatspktsover1522octets, stats_rx.rx_stat_etherstatspktsover1522octets); 2476 LM_STATS_HW_MAC_ASSIGN_U32(stats_tx.tx_stat_ifhcoutoctets, stats_tx.tx_stat_ifhcoutoctets); 2477 LM_STATS_HW_MAC_ASSIGN_U32(stats_tx.tx_stat_ifhcoutucastpkts, stats_tx.tx_stat_ifhcoutucastpkts); 2478 LM_STATS_HW_MAC_ASSIGN_U32(stats_tx.tx_stat_ifhcoutmulticastpkts, stats_tx.tx_stat_ifhcoutmulticastpkts); 2479 LM_STATS_HW_MAC_ASSIGN_U32(stats_tx.tx_stat_ifhcoutbroadcastpkts, stats_tx.tx_stat_ifhcoutbroadcastpkts); 2480 } 2481 2482 LM_STATS_HW_MAC_ASSIGN_U32(stats_rx.rx_stat_dot3statsfcserrors, stats_rx.rx_stat_dot3statsfcserrors ) ; 2483 LM_STATS_HW_MAC_ASSIGN_U32(stats_rx.rx_stat_dot3statsalignmenterrors, stats_rx.rx_stat_dot3statsalignmenterrors ) ; 2484 LM_STATS_HW_MAC_ASSIGN_U32(stats_rx.rx_stat_dot3statscarriersenseerrors, stats_rx.rx_stat_dot3statscarriersenseerrors ) ; 2485 LM_STATS_HW_MAC_ASSIGN_U32(stats_rx.rx_stat_xonpauseframesreceived, stats_rx.rx_stat_xonpauseframesreceived ) ; 2486 LM_STATS_HW_MAC_ASSIGN_U32(stats_rx.rx_stat_xoffpauseframesreceived, stats_rx.rx_stat_xoffpauseframesreceived ) ; 2487 LM_STATS_HW_MAC_ASSIGN_U32(stats_rx.rx_stat_maccontrolframesreceived, stats_rx.rx_stat_maccontrolframesreceived ) ; 2488 LM_STATS_HW_MAC_ASSIGN_U32(stats_rx.rx_stat_xoffstateentered, stats_rx.rx_stat_xoffstateentered ) ; 2489 LM_STATS_HW_MAC_ASSIGN_U32(stats_rx.rx_stat_dot3statsframestoolong, stats_rx.rx_stat_dot3statsframestoolong ) ; 2490 LM_STATS_HW_MAC_ASSIGN_U32(stats_rx.rx_stat_etherstatsjabbers, stats_rx.rx_stat_etherstatsjabbers ) ; 2491 LM_STATS_HW_MAC_ASSIGN_U32(stats_rx.rx_stat_etherstatsundersizepkts, stats_rx.rx_stat_etherstatsundersizepkts ) ; 2492 2493 2494 LM_STATS_HW_MAC_ASSIGN_U32(stats_rx_err.rx_stat_falsecarriererrors, stats_rx_err.rx_stat_falsecarriererrors ) ; 2495 2496 2497 2498 LM_STATS_HW_MAC_ASSIGN_U32(stats_tx.tx_stat_ifhcoutbadoctets, stats_tx.tx_stat_ifhcoutbadoctets ) ; 2499 LM_STATS_HW_MAC_ASSIGN_U32(stats_tx.tx_stat_etherstatscollisions, stats_tx.tx_stat_etherstatscollisions ) ; 2500 LM_STATS_HW_MAC_ASSIGN_U32(stats_tx.tx_stat_outxonsent, stats_tx.tx_stat_outxonsent ) ; 2501 LM_STATS_HW_MAC_ASSIGN_U32(stats_tx.tx_stat_outxoffsent, stats_tx.tx_stat_outxoffsent ) ; 2502 LM_STATS_HW_MAC_ASSIGN_U32(stats_tx.tx_stat_flowcontroldone, stats_tx.tx_stat_flowcontroldone ) ; 2503 LM_STATS_HW_MAC_ASSIGN_U32(stats_tx.tx_stat_dot3statssinglecollisionframes, stats_tx.tx_stat_dot3statssinglecollisionframes ) ; 2504 LM_STATS_HW_MAC_ASSIGN_U32(stats_tx.tx_stat_dot3statsmultiplecollisionframes, stats_tx.tx_stat_dot3statsmultiplecollisionframes ) ; 2505 LM_STATS_HW_MAC_ASSIGN_U32(stats_tx.tx_stat_dot3statsdeferredtransmissions, stats_tx.tx_stat_dot3statsdeferredtransmissions ) ; 2506 LM_STATS_HW_MAC_ASSIGN_U32(stats_tx.tx_stat_dot3statsexcessivecollisions, stats_tx.tx_stat_dot3statsexcessivecollisions ) ; 2507 LM_STATS_HW_MAC_ASSIGN_U32(stats_tx.tx_stat_dot3statslatecollisions, stats_tx.tx_stat_dot3statslatecollisions ) ; 2508 2509 2510 LM_STATS_HW_MAC_ASSIGN_U32(stats_tx.tx_stat_etherstatspkts64octets, stats_tx.tx_stat_etherstatspkts64octets ) ; 2511 LM_STATS_HW_MAC_ASSIGN_U32(stats_tx.tx_stat_etherstatspkts65octetsto127octets, stats_tx.tx_stat_etherstatspkts65octetsto127octets ) ; 2512 LM_STATS_HW_MAC_ASSIGN_U32(stats_tx.tx_stat_etherstatspkts128octetsto255octets, stats_tx.tx_stat_etherstatspkts128octetsto255octets ) ; 2513 LM_STATS_HW_MAC_ASSIGN_U32(stats_tx.tx_stat_etherstatspkts256octetsto511octets, stats_tx.tx_stat_etherstatspkts256octetsto511octets ) ; 2514 LM_STATS_HW_MAC_ASSIGN_U32(stats_tx.tx_stat_etherstatspkts512octetsto1023octets, stats_tx.tx_stat_etherstatspkts512octetsto1023octets ) ; 2515 LM_STATS_HW_MAC_ASSIGN_U32(stats_tx.tx_stat_etherstatspkts1024octetsto1522octet, stats_tx.tx_stat_etherstatspkts1024octetsto1522octet ) ; 2516 LM_STATS_HW_MAC_ASSIGN_U32(stats_tx.tx_stat_etherstatspktsover1522octets, stats_tx.tx_stat_etherstatspktsover1522octets ) ; 2517 LM_STATS_HW_MAC_ASSIGN_U32(stats_tx.tx_stat_dot3statsinternalmactransmiterrors, stats_tx.tx_stat_dot3statsinternalmactransmiterrors ) ; 2518 } 2519 2520 void lm_stats_hw_assign( struct _lm_device_t *pdev ) 2521 { 2522 if(HAS_MSTAT(pdev)) 2523 { 2524 DbgMessage(pdev, INFORM, "lm_stats_hw_assign: device has MSTAT block.\n"); 2525 lm_stats_hw_mstat_assign(pdev); 2526 } 2527 else if (CHIP_IS_E2(pdev) && (pdev->vars.mac_type == MAC_TYPE_BMAC)) 2528 { 2529 lm_stats_hw_bmac2_assign(pdev); 2530 } 2531 else if (pdev->vars.mac_type == MAC_TYPE_BMAC) 2532 { 2533 lm_stats_hw_bmac1_assign(pdev); 2534 } 2535 else if(pdev->vars.mac_type == MAC_TYPE_EMAC) 2536 { 2537 lm_stats_hw_emac_assign(pdev); 2538 } 2539 else 2540 { 2541 DbgBreakIf((pdev->vars.mac_type != MAC_TYPE_EMAC) && (pdev->vars.mac_type == MAC_TYPE_BMAC) && !HAS_MSTAT(pdev) ); 2542 } 2543 2544 //nig 2545 { 2546 LM_STATS_HW_NIG_ASSIGN_U32(nig, brb_discard, brb_discard ) ; 2547 if (!IS_MULTI_VNIC(pdev)) 2548 { 2549 LM_STATS_HW_NIG_ASSIGN_U32(nig, brb_packet, brb_packet ); 2550 LM_STATS_HW_NIG_ASSIGN_U32(nig, brb_truncate, brb_truncate ); 2551 LM_STATS_HW_NIG_ASSIGN_U32(nig, flow_ctrl_discard, flow_ctrl_discard ); 2552 LM_STATS_HW_NIG_ASSIGN_U32(nig, flow_ctrl_octets, flow_ctrl_octets ); 2553 LM_STATS_HW_NIG_ASSIGN_U32(nig, flow_ctrl_packet, flow_ctrl_packet ); 2554 LM_STATS_HW_NIG_ASSIGN_U32(nig, mng_discard, mng_discard ); 2555 LM_STATS_HW_NIG_ASSIGN_U32(nig, mng_octet_inp, mng_octet_inp ); 2556 LM_STATS_HW_NIG_ASSIGN_U32(nig, mng_octet_out, mng_octet_out ); 2557 LM_STATS_HW_NIG_ASSIGN_U32(nig, mng_packet_inp, mng_packet_inp ); 2558 LM_STATS_HW_NIG_ASSIGN_U32(nig, mng_packet_out, mng_packet_out ); 2559 LM_STATS_HW_NIG_ASSIGN_U32(nig, pbf_octets, pbf_octets ); 2560 LM_STATS_HW_NIG_ASSIGN_U32(nig, pbf_packet, pbf_packet ); 2561 LM_STATS_HW_NIG_ASSIGN_U32(nig, safc_inp, safc_inp ); 2562 } 2563 if(HAS_MSTAT(pdev))//E3 has no NIG-ex registers, so we use values from MSTAT instead. 2564 { 2565 //Note: this must occur after the other HW stats have been assigned. 2566 stats_macs_t* assigned_hw_stats = &pdev->vars.stats.stats_mirror.stats_hw.macs[STATS_MACS_IDX_TOTAL]; 2567 struct _stats_nig_ex_t* nig_ex_stats = &pdev->vars.stats.stats_collect.stats_hw.nig_ex_stats_query; 2568 /*NIG pkt0 counts packets with sizes 1024-1522 bytes. MSTAT has an equivalent register.*/ 2569 nig_ex_stats->egress_mac_pkt0 = assigned_hw_stats->stats_tx.tx_stat_etherstatspkts1024octetsto1522octet; 2570 /*NIG pkt1 counts packets of size 1523 and up. We sum the required MSTAT values to get the right result. 2571 Note that the field names are somewhat misleading, since they don't count sizes 1522-XXXX but [1522-2047],[2048-4095],[4096-9216],[9217-14383] 2572 (see MSTAT low level design document). 2573 */ 2574 nig_ex_stats->egress_mac_pkt1 = assigned_hw_stats->stats_tx.tx_stat_etherstatspktsover1522octets_bmac_2047+ 2575 assigned_hw_stats->stats_tx.tx_stat_etherstatspktsover1522octets_bmac_4095+ 2576 assigned_hw_stats->stats_tx.tx_stat_etherstatspktsover1522octets_bmac_9216+ 2577 assigned_hw_stats->stats_tx.tx_stat_etherstatspktsover1522octets_bmac_16383; 2578 } 2579 else 2580 { 2581 LM_SIGN_EXTEND_VALUE_36( pdev->vars.stats.stats_collect.stats_hw.nig_ex_stats_query.egress_mac_pkt0, pdev->vars.stats.stats_mirror.stats_hw.nig_ex.egress_mac_pkt0 ) ; 2582 LM_SIGN_EXTEND_VALUE_36( pdev->vars.stats.stats_collect.stats_hw.nig_ex_stats_query.egress_mac_pkt1, pdev->vars.stats.stats_mirror.stats_hw.nig_ex.egress_mac_pkt1 ) ; 2583 } 2584 } 2585 } 2586 2587 /* 2588 *Function Name: lm_drv_info_to_mfw_assign_eth 2589 * 2590 *Parameters: 2591 * 2592 *Description: 2593 * assign drv_info eth stats from different places in the pdev to "mirror" (vars.stats.stats_mirror.stats_drv.drv_info_to_mfw.eth_stats) 2594 *Returns: 2595 * 2596 */ 2597 static void lm_drv_info_to_mfw_assign_eth( struct _lm_device_t *pdev ) 2598 { 2599 const u8_t client_id = LM_CLI_CID(pdev, LM_CLI_IDX_NDIS ); 2600 eth_stats_info_t* stats_eth = &pdev->vars.stats.stats_mirror.stats_drv.drv_info_to_mfw.eth_stats; 2601 lm_client_con_params_t* cli_params = NULL; 2602 2603 if( client_id >= ARRSIZE(pdev->params.l2_cli_con_params) ) 2604 { 2605 DbgBreakIf( client_id >= ARRSIZE(pdev->params.l2_cli_con_params) ); 2606 return; 2607 } 2608 2609 #define DRV_INFO_TO_MFW_NOT_SUPPORTED 0 2610 2611 cli_params = &pdev->params.l2_cli_con_params[client_id]; 2612 2613 ASSERT_STATIC( sizeof(stats_eth->version) <= sizeof(pdev->ver_str) ); 2614 2615 ASSERT_STATIC( sizeof(stats_eth->mac_local) <= sizeof( pdev->params.mac_addr ) ); 2616 2617 mm_memcpy( stats_eth->version, pdev->ver_str, sizeof(stats_eth->version) ); 2618 2619 /* Locally Admin Addr. BigEndian EIU48. Actual size is 6 bytes */ 2620 /* Additional Programmed MAC Addr 1. 2*/ 2621 2622 // stats_eth->mac_local, mac_add1, mac_add2 - NO NEED to update here since they are already updated in lm_eq_handle_classification_eqe 2623 2624 /* MTU Size. Note : Negotiated MTU */ 2625 stats_eth->mtu_size = cli_params->mtu; 2626 2627 /* LSO MaxOffloadSize. */ 2628 stats_eth->lso_max_size = DRV_INFO_TO_MFW_NOT_SUPPORTED; // we should acquire this from NDIS? 2629 2630 /* LSO MinSegmentCount. */ 2631 stats_eth->lso_min_seg_cnt = DRV_INFO_TO_MFW_NOT_SUPPORTED; // we should acquire this from NDIS? 2632 2633 /* Num Offloaded Connections TCP_IPv4. */ 2634 stats_eth->ipv4_ofld_cnt = pdev->vars.stats.stats_mirror.stats_drv.drv_toe.ipv[STATS_IP_4_IDX].currently_established; 2635 2636 /* Num Offloaded Connections TCP_IPv6. */ 2637 stats_eth->ipv6_ofld_cnt = pdev->vars.stats.stats_mirror.stats_drv.drv_toe.ipv[STATS_IP_6_IDX].currently_established; 2638 2639 /* Promiscuous Mode. non-zero true */ 2640 stats_eth->promiscuous_mode = ( 0 != GET_FLAGS( pdev->client_info[client_id].last_set_rx_mask, LM_RX_MASK_PROMISCUOUS_MODE ) ); 2641 2642 /* TX Descriptors Queue Size */ 2643 stats_eth->txq_size = cli_params->num_tx_desc; 2644 2645 /* RX Descriptors Queue Size */ 2646 stats_eth->rxq_size = cli_params->num_rx_desc;//= pdev->params.l2_rx_desc_cnt[LM_CLI_IDX_NDIS]; 2647 2648 /* TX Descriptor Queue Avg Depth. % Avg Queue Depth since last poll */ 2649 stats_eth->txq_avg_depth = DRV_INFO_TO_MFW_NOT_SUPPORTED; 2650 2651 /* RX Descriptors Queue Avg Depth. % Avg Queue Depth since last poll */ 2652 stats_eth->rxq_avg_depth = DRV_INFO_TO_MFW_NOT_SUPPORTED; 2653 2654 /* IOV_Offload. 0=none; 1=MultiQueue, 2=VEB 3= VEPA*/ 2655 stats_eth->iov_offload = DRV_INFO_TO_MFW_NOT_SUPPORTED; 2656 2657 /* Num VF assigned to this PF. */ 2658 stats_eth->vf_cnt = 0; // Once Win8 (T7.4) should be changed! 2659 2660 /* Number of NetQueue/VMQ Config'd. */ 2661 stats_eth->netq_cnt = mm_get_vmq_cnt(pdev); 2662 2663 /* Feature_Flags. */ 2664 stats_eth->feature_flags = mm_get_feature_flags(pdev); 2665 } /* lm_drv_info_to_mfw_assign_eth */ 2666 2667 2668 /* 2669 *Function Name: lm_stats_drv_info_to_mfw_assign 2670 * 2671 *Parameters: 2672 * 2673 *Description: 2674 * Upon the opcode assign relevant stats from "mirror" to physical memory in "collect" 2675 * then, MFW will read this data. 2676 *Returns: 2677 * 2678 */ 2679 lm_status_t lm_stats_drv_info_to_mfw_assign( struct _lm_device_t *pdev, const enum drv_info_opcode drv_info_op ) 2680 { 2681 lm_status_t lm_status = LM_STATUS_SUCCESS; 2682 void* dest = (void*)pdev->vars.stats.stats_collect.drv_info_to_mfw.addr.eth_stats; // this is a union so doesn't matter if etc/iscsi/fcoe 2683 void* src = NULL; 2684 u32_t size = 0; 2685 2686 if CHK_NULL(dest) 2687 { 2688 // dest might be NULL if we got here in chip id < E3 2689 DbgBreakIf(!dest); 2690 return LM_STATUS_FAILURE; 2691 } 2692 2693 switch(drv_info_op) 2694 { 2695 case ETH_STATS_OPCODE: 2696 // We gather eth stats from already known data 2697 lm_drv_info_to_mfw_assign_eth(pdev); 2698 2699 src = &pdev->vars.stats.stats_mirror.stats_drv.drv_info_to_mfw.eth_stats; 2700 size = sizeof(pdev->vars.stats.stats_mirror.stats_drv.drv_info_to_mfw.eth_stats); 2701 break; 2702 2703 case ISCSI_STATS_OPCODE: 2704 // storage data is set by miniport 2705 src = &pdev->vars.stats.stats_mirror.stats_drv.drv_info_to_mfw.iscsi_stats; 2706 size = sizeof(pdev->vars.stats.stats_mirror.stats_drv.drv_info_to_mfw.iscsi_stats); 2707 break; 2708 2709 case FCOE_STATS_OPCODE: 2710 // storage data is set by miniport 2711 src = &pdev->vars.stats.stats_mirror.stats_drv.drv_info_to_mfw.fcoe_stats; 2712 size = sizeof(pdev->vars.stats.stats_mirror.stats_drv.drv_info_to_mfw.fcoe_stats); 2713 break; 2714 2715 default: 2716 lm_status = LM_STATUS_INVALID_PARAMETER; 2717 break; 2718 } 2719 2720 if( LM_STATUS_SUCCESS == lm_status) 2721 { 2722 // Zero buffer 2723 mm_mem_zero( dest, size ); 2724 2725 // Copy relevant field 2726 mm_memcpy( dest, src, size ); 2727 } 2728 2729 return lm_status; 2730 } /* lm_stats_drv_info_to_mfw_assign */ 2731 2732 // resets mirror fw statistics 2733 void lm_stats_fw_reset( struct _lm_device_t* pdev) 2734 { 2735 if CHK_NULL( pdev ) 2736 { 2737 DbgBreakIf(!pdev) ; 2738 } 2739 mm_memset( &pdev->vars.stats.stats_mirror.stats_fw, 0, sizeof(pdev->vars.stats.stats_mirror.stats_fw) ) ; 2740 } 2741 2742 void lm_stats_get_dcb_stats( lm_device_t* pdev, lm_dcbx_stat *stats ) 2743 { 2744 stats->pfc_frames_sent = (LM_STATS_HW_GET_MACS_U64( pdev, stats_tx.tx_stat_pfcPacketCounter ) ); 2745 stats->pfc_frames_received = (LM_STATS_HW_GET_MACS_U64( pdev, stats_rx.rx_stat_pfcPacketCounter ) ); 2746 } 2747 void lm_stats_get_driver_stats( struct _lm_device_t* pdev, b10_driver_statistics_t *stats ) 2748 { 2749 stats->ver_num = DRIVER_STATISTISTCS_VER_NUM; 2750 stats->tx_lso_frames = pdev->vars.stats.stats_mirror.stats_drv.drv_eth.tx_lso_frames ; 2751 stats->tx_aborted = pdev->vars.stats.stats_mirror.stats_drv.drv_eth.tx_aborted ; 2752 stats->tx_no_bd = 0 ; 2753 stats->tx_no_desc = 0 ; 2754 stats->tx_no_coalesce_buf = pdev->vars.stats.stats_mirror.stats_drv.drv_eth.tx_no_coalesce_buf ; 2755 stats->tx_no_map_reg = 0 ; 2756 stats->rx_aborted = pdev->vars.stats.stats_mirror.stats_drv.drv_eth.rx_aborted ; 2757 stats->rx_err = 0 ; 2758 stats->rx_crc = 0 ; 2759 stats->rx_phy_err = 0 ; 2760 stats->rx_alignment = 0; 2761 stats->rx_short_packet = 0 ; 2762 stats->rx_giant_packet = 0 ; 2763 } 2764 2765 void lm_stats_get_l2_driver_stats( struct _lm_device_t* pdev, b10_l2_driver_statistics_t *stats ) 2766 { 2767 stats->ver_num = L2_DRIVER_STATISTISTCS_VER_NUM; 2768 stats->RxIPv4FragCount = pdev->vars.stats.stats_mirror.stats_drv.drv_eth.rx_ipv4_frag_count ; 2769 stats->RxIpCsErrorCount = pdev->vars.stats.stats_mirror.stats_drv.drv_eth.rx_ip_cs_error_count ; 2770 stats->RxTcpCsErrorCount = pdev->vars.stats.stats_mirror.stats_drv.drv_eth.rx_tcp_cs_error_count ; 2771 stats->RxLlcSnapCount = pdev->vars.stats.stats_mirror.stats_drv.drv_eth.rx_llc_snap_count ; 2772 stats->RxPhyErrorCount = pdev->vars.stats.stats_mirror.stats_drv.drv_eth.rx_phy_error_count ; 2773 stats->RxIpv6ExtCount = pdev->vars.stats.stats_mirror.stats_drv.drv_eth.rx_ipv6_ext_count ; 2774 stats->TxNoL2Bd = pdev->vars.stats.stats_mirror.stats_drv.drv_eth.tx_no_l2_bd ; 2775 stats->TxNoSqWqe = pdev->vars.stats.stats_mirror.stats_drv.drv_eth.tx_no_sq_wqe ; 2776 stats->TxL2AssemblyBufUse = pdev->vars.stats.stats_mirror.stats_drv.drv_eth.tx_l2_assembly_buf_use ; 2777 } 2778 void lm_stats_get_l4_driver_stats( struct _lm_device_t* pdev, b10_l4_driver_statistics_t *stats ) 2779 { 2780 u8_t idx = 0 ; 2781 2782 stats->ver_num = L4_DRIVER_STATISTISTCS_VER_NUM; 2783 2784 idx = STATS_IP_4_IDX ; 2785 stats->CurrentlyIpv4Established = pdev->vars.stats.stats_mirror.stats_drv.drv_toe.ipv[idx].currently_established ; 2786 stats->OutIpv4Resets = pdev->vars.stats.stats_mirror.stats_drv.drv_toe.ipv[idx].out_resets ; 2787 stats->OutIpv4Fin = pdev->vars.stats.stats_mirror.stats_drv.drv_toe.ipv[idx].out_fin ; 2788 stats->InIpv4Reset = pdev->vars.stats.stats_mirror.stats_drv.drv_toe.ipv[idx].in_reset ; 2789 stats->InIpv4Fin = pdev->vars.stats.stats_mirror.stats_drv.drv_toe.ipv[idx].in_fin ; 2790 2791 idx = STATS_IP_6_IDX ; 2792 stats->CurrentlyIpv6Established = pdev->vars.stats.stats_mirror.stats_drv.drv_toe.ipv[idx].currently_established ; 2793 stats->OutIpv6Resets = pdev->vars.stats.stats_mirror.stats_drv.drv_toe.ipv[idx].out_resets ; 2794 stats->OutIpv6Fin = pdev->vars.stats.stats_mirror.stats_drv.drv_toe.ipv[idx].out_fin ; 2795 stats->InIpv6Reset = pdev->vars.stats.stats_mirror.stats_drv.drv_toe.ipv[idx].in_reset ; 2796 stats->InIpv6Fin = pdev->vars.stats.stats_mirror.stats_drv.drv_toe.ipv[idx].in_fin ; 2797 2798 stats->RxIndicateReturnPendingCnt = pdev->vars.stats.stats_mirror.stats_drv.drv_toe.rx_indicate_return_pending_cnt ; 2799 stats->RxIndicateReturnDoneCnt = pdev->vars.stats.stats_mirror.stats_drv.drv_toe.rx_indicate_return_done_cnt ; 2800 stats->RxActiveGenBufCnt = pdev->vars.stats.stats_mirror.stats_drv.drv_toe.rx_active_gen_buf_cnt ; 2801 stats->TxNoL4Bd = pdev->vars.stats.stats_mirror.stats_drv.drv_toe.tx_no_l4_bd ; 2802 stats->TxL4AssemblyBufUse = pdev->vars.stats.stats_mirror.stats_drv.drv_toe.tx_l4_assembly_buf_use ; 2803 } 2804 2805 void lm_stats_get_l2_chip_stats( struct _lm_device_t* pdev, void *buf, u8_t version) 2806 { 2807 u32_t idx = LM_CLI_IDX_NDIS ; 2808 b10_l2_chip_statistics_t *stats = buf; 2809 2810 stats->ver_num = version ; 2811 2812 // TODO - change IOCTL structure to be per client 2813 2814 stats->IfHCInOctets = pdev->vars.stats.stats_mirror.stats_fw.eth_tstorm_common.client_statistics[idx].rcv_broadcast_bytes + 2815 pdev->vars.stats.stats_mirror.stats_fw.eth_tstorm_common.client_statistics[idx].rcv_multicast_bytes + 2816 pdev->vars.stats.stats_mirror.stats_fw.eth_tstorm_common.client_statistics[idx].rcv_unicast_bytes ; 2817 stats->IfHCInBadOctets = (LM_STATS_HW_GET_MACS_U64( pdev, stats_rx.rx_stat_ifhcinbadoctets ) ); 2818 stats->IfHCOutOctets = pdev->vars.stats.stats_mirror.stats_fw.eth_xstorm_common.client_statistics[idx].total_sent_bytes ; 2819 stats->IfHCOutBadOctets = (LM_STATS_HW_GET_MACS_U64( pdev, stats_tx.tx_stat_ifhcoutbadoctets ) ); 2820 stats->IfHCInUcastPkts = (pdev->vars.stats.stats_mirror.stats_fw.eth_tstorm_common.client_statistics[idx].rcv_unicast_pkts ) ; 2821 stats->IfHCInMulticastPkts = (pdev->vars.stats.stats_mirror.stats_fw.eth_tstorm_common.client_statistics[idx].rcv_multicast_pkts ) ; 2822 stats->IfHCInBroadcastPkts = (pdev->vars.stats.stats_mirror.stats_fw.eth_tstorm_common.client_statistics[idx].rcv_broadcast_pkts ) ; 2823 stats->IfHCInUcastOctets = (pdev->vars.stats.stats_mirror.stats_fw.eth_tstorm_common.client_statistics[idx].rcv_unicast_bytes ) ; 2824 stats->IfHCInMulticastOctets = (pdev->vars.stats.stats_mirror.stats_fw.eth_tstorm_common.client_statistics[idx].rcv_multicast_bytes ) ; 2825 stats->IfHCInBroadcastOctets = (pdev->vars.stats.stats_mirror.stats_fw.eth_tstorm_common.client_statistics[idx].rcv_broadcast_bytes ) ; 2826 2827 stats->IfHCOutUcastOctets = (pdev->vars.stats.stats_mirror.stats_fw.eth_xstorm_common.client_statistics[idx].unicast_bytes_sent ) ; 2828 stats->IfHCOutMulticastOctets = (pdev->vars.stats.stats_mirror.stats_fw.eth_xstorm_common.client_statistics[idx].multicast_bytes_sent ) ; 2829 stats->IfHCOutBroadcastOctets = (pdev->vars.stats.stats_mirror.stats_fw.eth_xstorm_common.client_statistics[idx].broadcast_bytes_sent ) ; 2830 stats->IfHCOutPkts = (pdev->vars.stats.stats_mirror.stats_fw.eth_xstorm_common.client_statistics[idx].total_sent_pkts ) ; 2831 2832 2833 lm_get_stats( pdev, LM_STATS_UNICAST_FRAMES_XMIT, &stats->IfHCOutUcastPkts 2834 #ifdef VF_INVOLVED 2835 ,NULL 2836 #endif 2837 ) ; 2838 lm_get_stats( pdev, LM_STATS_MULTICAST_FRAMES_XMIT, &stats->IfHCOutMulticastPkts 2839 #ifdef VF_INVOLVED 2840 ,NULL 2841 #endif 2842 ) ; 2843 lm_get_stats( pdev, LM_STATS_BROADCAST_FRAMES_XMIT, &stats->IfHCOutBroadcastPkts 2844 #ifdef VF_INVOLVED 2845 ,NULL 2846 #endif 2847 ) ; 2848 2849 stats->IfHCInPkts = pdev->vars.stats.stats_mirror.stats_fw.eth_tstorm_common.client_statistics[idx].rcv_broadcast_pkts + 2850 pdev->vars.stats.stats_mirror.stats_fw.eth_tstorm_common.client_statistics[idx].rcv_multicast_pkts + 2851 pdev->vars.stats.stats_mirror.stats_fw.eth_tstorm_common.client_statistics[idx].rcv_unicast_pkts ; 2852 2853 stats->IfHCOutDiscards = (LM_STATS_HW_GET_MACS_U64( pdev, stats_tx.tx_stat_ifhcoutdiscards ) ); 2854 stats->IfHCInFalseCarrierErrors = (LM_STATS_HW_GET_MACS_U64( pdev, stats_rx_err.rx_stat_falsecarriererrors ) ); 2855 2856 stats->Dot3StatsInternalMacTransmitErrors = (LM_STATS_HW_GET_MACS_U64( pdev, stats_tx.tx_stat_dot3statsinternalmactransmiterrors )) ; 2857 stats->Dot3StatsCarrierSenseErrors = (LM_STATS_HW_GET_MACS_U64( pdev, stats_rx.rx_stat_dot3statscarriersenseerrors )) ; 2858 stats->Dot3StatsFCSErrors = (LM_STATS_HW_GET_MACS_U64( pdev, stats_rx.rx_stat_dot3statsfcserrors )) ; 2859 stats->Dot3StatsAlignmentErrors = (LM_STATS_HW_GET_MACS_U64( pdev, stats_rx.rx_stat_dot3statsalignmenterrors )) ; 2860 stats->Dot3StatsSingleCollisionFrames = (LM_STATS_HW_GET_MACS_U64( pdev, stats_tx.tx_stat_dot3statssinglecollisionframes )) ; 2861 stats->Dot3StatsMultipleCollisionFrames = (LM_STATS_HW_GET_MACS_U64( pdev, stats_tx.tx_stat_dot3statsmultiplecollisionframes )) ; 2862 stats->Dot3StatsDeferredTransmissions = (LM_STATS_HW_GET_MACS_U64( pdev, stats_tx.tx_stat_dot3statsdeferredtransmissions )) ; 2863 stats->Dot3StatsExcessiveCollisions = (LM_STATS_HW_GET_MACS_U64( pdev, stats_tx.tx_stat_dot3statsexcessivecollisions )) ; 2864 stats->Dot3StatsLateCollisions = (LM_STATS_HW_GET_MACS_U64( pdev, stats_tx.tx_stat_dot3statslatecollisions )) ; 2865 stats->EtherStatsCollisions = (LM_STATS_HW_GET_MACS_U64( pdev, stats_tx.tx_stat_etherstatscollisions )) ; 2866 stats->EtherStatsFragments = (LM_STATS_HW_GET_MACS_U64( pdev, stats_rx.rx_stat_etherstatsfragments )) ; 2867 stats->EtherStatsJabbers = (LM_STATS_HW_GET_MACS_U64( pdev, stats_rx.rx_stat_etherstatsjabbers )) ; 2868 2869 2870 stats->EtherStatsUndersizePkts = (LM_STATS_HW_GET_MACS_U64( pdev, stats_rx.rx_stat_etherstatsundersizepkts )) ; 2871 stats->EtherStatsOverrsizePkts = (LM_STATS_HW_GET_MACS_U64( pdev, stats_rx.rx_stat_dot3statsframestoolong )) ; 2872 2873 stats->EtherStatsPktsTx64Octets = (LM_STATS_HW_GET_MACS_U64( pdev, stats_tx.tx_stat_etherstatspkts64octets )) ; 2874 stats->EtherStatsPktsTx65Octetsto127Octets = (LM_STATS_HW_GET_MACS_U64( pdev, stats_tx.tx_stat_etherstatspkts65octetsto127octets )) ; 2875 stats->EtherStatsPktsTx128Octetsto255Octets = (LM_STATS_HW_GET_MACS_U64( pdev, stats_tx.tx_stat_etherstatspkts128octetsto255octets )) ; 2876 stats->EtherStatsPktsTx256Octetsto511Octets = (LM_STATS_HW_GET_MACS_U64( pdev, stats_tx.tx_stat_etherstatspkts256octetsto511octets )) ; 2877 stats->EtherStatsPktsTx512Octetsto1023Octets = (LM_STATS_HW_GET_MACS_U64( pdev, stats_tx.tx_stat_etherstatspkts512octetsto1023octets)) ; 2878 stats->EtherStatsPktsTx1024Octetsto1522Octets = (pdev->vars.stats.stats_mirror.stats_hw.nig_ex.egress_mac_pkt0) ; 2879 stats->EtherStatsPktsTxOver1522Octets = (pdev->vars.stats.stats_mirror.stats_hw.nig_ex.egress_mac_pkt1) ; 2880 2881 stats->XonPauseFramesReceived = (LM_STATS_HW_GET_MACS_U64( pdev, stats_rx.rx_stat_xonpauseframesreceived )) ; 2882 stats->XoffPauseFramesReceived = (LM_STATS_HW_GET_MACS_U64( pdev, stats_rx.rx_stat_xoffpauseframesreceived )) ; 2883 stats->OutXonSent = (LM_STATS_HW_GET_MACS_U64( pdev, stats_tx.tx_stat_outxonsent )) ; 2884 2885 stats->OutXoffSent = (LM_STATS_HW_GET_MACS_U64( pdev, stats_tx.tx_stat_outxoffsent )) ; 2886 2887 stats->FlowControlDone = (LM_STATS_HW_GET_MACS_U64( pdev, stats_tx.tx_stat_flowcontroldone )) ; 2888 2889 stats->MacControlFramesReceived = (LM_STATS_HW_GET_MACS_U64( pdev, stats_rx.rx_stat_maccontrolframesreceived )) ; 2890 stats->MacControlFramesReceived += (LM_STATS_HW_GET_MACS_U64( pdev, stats_rx.rx_stat_maccontrolframesreceived_bmac_xcf )) ; 2891 2892 stats->XoffStateEntered = (LM_STATS_HW_GET_MACS_U64( pdev, stats_rx.rx_stat_xoffstateentered )) ; 2893 lm_get_stats( pdev, LM_STATS_ERRORED_RECEIVE_CNT, &stats->IfInErrors 2894 #ifdef VF_INVOLVED 2895 ,NULL 2896 #endif 2897 ) ; 2898 // TBD - IfInErrorsOctets - naming and support 2899 stats->IfInErrorsOctets = 0; 2900 2901 stats->IfInNoBrbBuffer = (pdev->vars.stats.stats_mirror.stats_hw.nig.brb_discard) ; 2902 stats->IfInFramesL2FilterDiscards = (pdev->vars.stats.stats_mirror.stats_fw.eth_tstorm_common.port_statistics.mac_filter_discard) ; 2903 stats->IfInTTL0Discards = (pdev->vars.stats.stats_mirror.stats_fw.eth_tstorm_common.client_statistics[idx].ttl0_discard) ; 2904 stats->IfInxxOverflowDiscards = (pdev->vars.stats.stats_mirror.stats_fw.eth_tstorm_common.port_statistics.xxoverflow_discard) ; 2905 2906 stats->IfInMBUFDiscards = (pdev->vars.stats.stats_mirror.stats_fw.eth_tstorm_common.client_statistics[idx].no_buff_discard ); 2907 stats->IfInMBUFDiscards += (pdev->vars.stats.stats_mirror.stats_fw.eth_ustorm_common.client_statistics[idx].ucast_no_buff_pkts ); 2908 stats->IfInMBUFDiscards += (pdev->vars.stats.stats_mirror.stats_fw.eth_ustorm_common.client_statistics[idx].mcast_no_buff_pkts ); 2909 stats->IfInMBUFDiscards += (pdev->vars.stats.stats_mirror.stats_fw.eth_ustorm_common.client_statistics[idx].bcast_no_buff_pkts ); 2910 2911 stats->Nig_brb_packet = (pdev->vars.stats.stats_mirror.stats_hw.nig.brb_packet) ; 2912 stats->Nig_brb_truncate = (pdev->vars.stats.stats_mirror.stats_hw.nig.brb_truncate) ; 2913 stats->Nig_flow_ctrl_discard = (pdev->vars.stats.stats_mirror.stats_hw.nig.flow_ctrl_discard) ; 2914 stats->Nig_flow_ctrl_octets = (pdev->vars.stats.stats_mirror.stats_hw.nig.flow_ctrl_octets) ; 2915 stats->Nig_flow_ctrl_packet = (pdev->vars.stats.stats_mirror.stats_hw.nig.flow_ctrl_packet) ; 2916 stats->Nig_mng_discard = (pdev->vars.stats.stats_mirror.stats_hw.nig.mng_discard) ; 2917 stats->Nig_mng_octet_inp = (pdev->vars.stats.stats_mirror.stats_hw.nig.mng_octet_inp) ; 2918 stats->Nig_mng_octet_out = (pdev->vars.stats.stats_mirror.stats_hw.nig.mng_octet_out) ; 2919 stats->Nig_mng_packet_inp = (pdev->vars.stats.stats_mirror.stats_hw.nig.mng_packet_inp) ; 2920 stats->Nig_mng_packet_out = (pdev->vars.stats.stats_mirror.stats_hw.nig.mng_packet_out) ; 2921 stats->Nig_pbf_octets = (pdev->vars.stats.stats_mirror.stats_hw.nig.pbf_octets) ; 2922 stats->Nig_pbf_packet = (pdev->vars.stats.stats_mirror.stats_hw.nig.pbf_packet) ; 2923 stats->Nig_safc_inp = (pdev->vars.stats.stats_mirror.stats_hw.nig.safc_inp) ; 2924 2925 if (version > L2_CHIP_STATISTICS_VER_NUM_1) 2926 { 2927 /* v2 statistics */ 2928 2929 b10_l2_chip_statistics_v2_t *stats_v2 = buf; 2930 2931 stats_v2->v2.Tx_lpi_count = pdev->vars.stats.stats_mirror.stats_hw.misc.tx_lpi_count; 2932 } 2933 2934 if (version > L2_CHIP_STATISTICS_VER_NUM_2) 2935 { 2936 b10_l2_chip_statistics_v3_t *stats_v3 = buf; 2937 stats_v3->v3.coalesced_pkts = pdev->vars.stats.stats_mirror.stats_fw.eth_ustorm_common.client_statistics[idx].coalesced_pkts; 2938 stats_v3->v3.coalesced_bytes = pdev->vars.stats.stats_mirror.stats_fw.eth_ustorm_common.client_statistics[idx].coalesced_bytes; 2939 stats_v3->v3.coalesced_events = pdev->vars.stats.stats_mirror.stats_fw.eth_ustorm_common.client_statistics[idx].coalesced_events; 2940 stats_v3->v3.coalesced_aborts = pdev->vars.stats.stats_mirror.stats_fw.eth_ustorm_common.client_statistics[idx].coalesced_aborts; 2941 } 2942 } 2943 2944 void lm_stats_get_l4_chip_stats( struct _lm_device_t* pdev, b10_l4_chip_statistics_t *stats ) 2945 { 2946 u8_t idx = 0 ; 2947 2948 stats->ver_num = L4_CHIP_STATISTISTCS_VER_NUM ; 2949 2950 stats->NoTxCqes = pdev->vars.stats.stats_mirror.stats_fw.toe_cstorm_toe.no_tx_cqes ; 2951 2952 // IP4 2953 idx = STATS_IP_4_IDX ; 2954 2955 stats->InTCP4Segments = pdev->vars.stats.stats_mirror.stats_fw.toe_tstorm_toe.statistics[idx].ip_in_receives ; 2956 stats->OutTCP4Segments = pdev->vars.stats.stats_mirror.stats_fw.toe_xstorm_toe.statistics[idx].tcp_out_segments ; 2957 stats->RetransmittedTCP4Segments = pdev->vars.stats.stats_mirror.stats_fw.toe_xstorm_toe.statistics[idx].tcp_retransmitted_segments ; 2958 stats->InTCP4Errors = pdev->vars.stats.stats_mirror.stats_fw.toe_tstorm_toe.statistics[idx].tcp_in_errors ; 2959 stats->InIP4Receives = pdev->vars.stats.stats_mirror.stats_fw.toe_tstorm_toe.statistics[idx].ip_in_receives ; 2960 stats->InIP4HeaderErrors = pdev->vars.stats.stats_mirror.stats_fw.toe_tstorm_toe.statistics[idx].ip_in_header_errors ; 2961 stats->InIP4Discards = pdev->vars.stats.stats_mirror.stats_fw.toe_tstorm_toe.statistics[idx].ip_in_discards ; 2962 stats->InIP4Delivers = pdev->vars.stats.stats_mirror.stats_fw.toe_tstorm_toe.statistics[idx].ip_in_delivers ; 2963 stats->InIP4Octets = pdev->vars.stats.stats_mirror.stats_fw.toe_tstorm_toe.statistics[idx].ip_in_octets ; 2964 stats->OutIP4Octets = pdev->vars.stats.stats_mirror.stats_fw.toe_xstorm_toe.statistics[idx].ip_out_octets ; 2965 stats->InIP4TruncatedPackets = pdev->vars.stats.stats_mirror.stats_fw.toe_tstorm_toe.statistics[idx].ip_in_truncated_packets ; 2966 2967 // IP6 2968 idx = STATS_IP_6_IDX ; 2969 2970 stats->InTCP6Segments = pdev->vars.stats.stats_mirror.stats_fw.toe_tstorm_toe.statistics[idx].ip_in_receives ; 2971 stats->OutTCP6Segments = pdev->vars.stats.stats_mirror.stats_fw.toe_xstorm_toe.statistics[idx].tcp_out_segments ; 2972 stats->RetransmittedTCP6Segments = pdev->vars.stats.stats_mirror.stats_fw.toe_xstorm_toe.statistics[idx].tcp_retransmitted_segments ; 2973 stats->InTCP6Errors = pdev->vars.stats.stats_mirror.stats_fw.toe_tstorm_toe.statistics[idx].tcp_in_errors ; 2974 stats->InIP6Receives = pdev->vars.stats.stats_mirror.stats_fw.toe_tstorm_toe.statistics[idx].ip_in_receives ; 2975 stats->InIP6HeaderErrors = pdev->vars.stats.stats_mirror.stats_fw.toe_tstorm_toe.statistics[idx].ip_in_header_errors ; 2976 stats->InIP6Discards = pdev->vars.stats.stats_mirror.stats_fw.toe_tstorm_toe.statistics[idx].ip_in_discards ; 2977 stats->InIP6Delivers = pdev->vars.stats.stats_mirror.stats_fw.toe_tstorm_toe.statistics[idx].ip_in_delivers ; 2978 stats->InIP6Octets = pdev->vars.stats.stats_mirror.stats_fw.toe_tstorm_toe.statistics[idx].ip_in_octets ; 2979 stats->OutIP6Octets = pdev->vars.stats.stats_mirror.stats_fw.toe_xstorm_toe.statistics[idx].ip_out_octets ; 2980 stats->InIP6TruncatedPackets = pdev->vars.stats.stats_mirror.stats_fw.toe_tstorm_toe.statistics[idx].ip_in_truncated_packets ; 2981 } 2982 2983 void lm_stats_hw_config_stats( struct _lm_device_t* pdev, u8_t b_enabled ) 2984 { 2985 DbgMessage(pdev, WARNstat, "lm_stats_hw_config_stats: b_collect_enabled %s-->%s\n", 2986 pdev->vars.stats.stats_collect.stats_hw.b_collect_enabled ? "TRUE":"FALSE", 2987 b_enabled ? "TRUE":"FALSE" ); 2988 2989 if (IS_PFDEV(pdev)) { 2990 pdev->vars.stats.stats_collect.stats_hw.b_collect_enabled = b_enabled ; 2991 } 2992 } 2993 2994 void lm_stats_fw_config_stats( struct _lm_device_t* pdev, u8_t b_enabled ) 2995 { 2996 DbgMessage(pdev, VERBOSEstat, "lm_stats_fw_config_stats: b_collect_enabled %s-->%s\n", 2997 pdev->vars.stats.stats_collect.stats_fw.b_collect_enabled ? "TRUE":"FALSE", 2998 b_enabled ? "TRUE":"FALSE" ); 2999 if (IS_PFDEV(pdev) || IS_CHANNEL_VFDEV(pdev)) { 3000 pdev->vars.stats.stats_collect.stats_fw.b_collect_enabled = b_enabled ; 3001 } 3002 } 3003 3004 /* 3005 *------------------------------------------------------------------------ 3006 * lm_stats_mgmt_assign_func 3007 * 3008 * assign values from different 'mirror' structures into host_func_stats_t structure 3009 * that will be sent later to mgmt 3010 * NOTE: function must be called under PHY_LOCK (since it uses REG_WR_DMAE interface) 3011 *------------------------------------------------------------------------ 3012 */ 3013 STATIC void lm_stats_mgmt_assign_func( IN struct _lm_device_t* pdev ) 3014 { 3015 u64_t val = 0 ; 3016 u64_t val_base = 0 ; 3017 lm_status_t lm_status = LM_STATUS_SUCCESS ; 3018 lm_stats_t stats_type = 0 ; 3019 host_func_stats_t* mcp_func = NULL ; 3020 host_func_stats_t* mcp_func_base = NULL ; 3021 3022 if CHK_NULL(pdev) 3023 { 3024 return; 3025 } 3026 3027 if ( GET_FLAGS(pdev->params.test_mode, TEST_MODE_NO_MCP ) ) 3028 { 3029 return; 3030 } 3031 3032 mcp_func = &pdev->vars.stats.stats_mirror.stats_mcp_func ; 3033 mcp_func_base = &pdev->vars.stats.stats_mirror.stats_mcp_func_base ; 3034 3035 stats_type = LM_STATS_BYTES_RCV ; 3036 lm_status = lm_get_stats( pdev, stats_type, &val 3037 #ifdef VF_INVOLVED 3038 ,NULL 3039 #endif 3040 ) ; 3041 if ERR_IF( LM_STATUS_SUCCESS != lm_status ) 3042 { 3043 DbgMessage(pdev, WARNstat, "lm_stats_mcp_assign: lm_get_stats type=0x%X failed. lm_status=0x%X", stats_type, lm_status ) ; 3044 } 3045 else 3046 { 3047 // calculate 'total' rcv (total+discards) 3048 val += (pdev->vars.stats.stats_mirror.stats_fw.eth_tstorm_common.client_statistics[LM_CLI_IDX_NDIS].rcv_error_bytes) ; 3049 3050 val+= LM_STATS_HI_LO_TO_64(mcp_func_base->total_bytes_received, val_base); 3051 mcp_func->total_bytes_received_hi = (u32_t)U64_HI( val ) ; 3052 mcp_func->total_bytes_received_lo = (u32_t)U64_LO( val ) ; 3053 } 3054 3055 stats_type = LM_STATS_BYTES_XMIT ; 3056 lm_status = lm_get_stats( pdev, stats_type, &val 3057 #ifdef VF_INVOLVED 3058 ,NULL 3059 #endif 3060 ) ; 3061 if ERR_IF( LM_STATUS_SUCCESS != lm_status ) 3062 { 3063 DbgMessage(pdev, WARNstat, "lm_stats_mcp_assign: lm_get_stats type=0x%X failed. lm_status=0x%X", stats_type, lm_status ) ; 3064 } 3065 else 3066 { 3067 val+= LM_STATS_HI_LO_TO_64(mcp_func_base->total_bytes_transmitted, val_base); 3068 mcp_func->total_bytes_transmitted_hi = (u32_t)U64_HI( val ) ; 3069 mcp_func->total_bytes_transmitted_lo = (u32_t)U64_LO( val ) ; 3070 } 3071 3072 stats_type = LM_STATS_UNICAST_FRAMES_RCV ; 3073 lm_status = lm_get_stats( pdev, stats_type, &val 3074 #ifdef VF_INVOLVED 3075 ,NULL 3076 #endif 3077 ) ; 3078 if ERR_IF( LM_STATUS_SUCCESS != lm_status ) 3079 { 3080 DbgMessage(pdev, WARNstat, "lm_stats_mcp_assign: lm_get_stats type=0x%X failed. lm_status=0x%X", stats_type, lm_status ) ; 3081 } 3082 else 3083 { 3084 val+= LM_STATS_HI_LO_TO_64(mcp_func_base->total_unicast_packets_received, val_base); 3085 mcp_func->total_unicast_packets_received_hi = (u32_t)U64_HI( val ) ; 3086 mcp_func->total_unicast_packets_received_lo = (u32_t)U64_LO( val ) ; 3087 } 3088 3089 stats_type = LM_STATS_MULTICAST_FRAMES_RCV ; 3090 lm_status = lm_get_stats( pdev, stats_type, &val 3091 #ifdef VF_INVOLVED 3092 ,NULL 3093 #endif 3094 ) ; 3095 if ERR_IF( LM_STATUS_SUCCESS != lm_status ) 3096 { 3097 DbgMessage(pdev, WARNstat, "lm_stats_mcp_assign: lm_get_stats type=0x%X failed. lm_status=0x%X", stats_type, lm_status ) ; 3098 } 3099 else 3100 { 3101 val+= LM_STATS_HI_LO_TO_64(mcp_func_base->total_multicast_packets_received, val_base); 3102 mcp_func->total_multicast_packets_received_hi = (u32_t)U64_HI( val ) ; 3103 mcp_func->total_multicast_packets_received_lo = (u32_t)U64_LO( val ) ; 3104 } 3105 3106 stats_type = LM_STATS_BROADCAST_FRAMES_RCV ; 3107 lm_status = lm_get_stats( pdev, stats_type, &val 3108 #ifdef VF_INVOLVED 3109 ,NULL 3110 #endif 3111 ) ; 3112 if ERR_IF( LM_STATUS_SUCCESS != lm_status ) 3113 { 3114 DbgMessage(pdev, WARNstat, "lm_stats_mcp_assign: lm_get_stats type=0x%X failed. lm_status=0x%X", stats_type, lm_status ) ; 3115 } 3116 else 3117 { 3118 val+= LM_STATS_HI_LO_TO_64(mcp_func_base->total_broadcast_packets_received, val_base); 3119 mcp_func->total_broadcast_packets_received_hi = (u32_t)U64_HI( val ) ; 3120 mcp_func->total_broadcast_packets_received_lo = (u32_t)U64_LO( val ) ; 3121 } 3122 3123 stats_type = LM_STATS_UNICAST_FRAMES_XMIT ; 3124 lm_status = lm_get_stats( pdev, stats_type, &val 3125 #ifdef VF_INVOLVED 3126 ,NULL 3127 #endif 3128 ) ; 3129 if ERR_IF( LM_STATUS_SUCCESS != lm_status ) 3130 { 3131 DbgMessage(pdev, WARNstat, "lm_stats_mcp_assign: lm_get_stats type=0x%X failed. lm_status=0x%X", stats_type, lm_status ) ; 3132 } 3133 else 3134 { 3135 val+= LM_STATS_HI_LO_TO_64(mcp_func_base->total_unicast_packets_transmitted, val_base); 3136 mcp_func->total_unicast_packets_transmitted_hi = (u32_t)U64_HI( val ) ; 3137 mcp_func->total_unicast_packets_transmitted_lo = (u32_t)U64_LO( val ) ; 3138 } 3139 3140 stats_type = LM_STATS_MULTICAST_FRAMES_XMIT ; 3141 lm_status = lm_get_stats( pdev, stats_type, &val 3142 #ifdef VF_INVOLVED 3143 ,NULL 3144 #endif 3145 ) ; 3146 if ERR_IF( LM_STATUS_SUCCESS != lm_status ) 3147 { 3148 DbgMessage(pdev, WARNstat, "lm_stats_mcp_assign: lm_get_stats type=0x%X failed. lm_status=0x%X", stats_type, lm_status ) ; 3149 } 3150 else 3151 { 3152 val+= LM_STATS_HI_LO_TO_64(mcp_func_base->total_multicast_packets_transmitted, val_base); 3153 mcp_func->total_multicast_packets_transmitted_hi = (u32_t)U64_HI( val ) ; 3154 mcp_func->total_multicast_packets_transmitted_lo = (u32_t)U64_LO( val ) ; 3155 } 3156 3157 stats_type = LM_STATS_BROADCAST_FRAMES_XMIT ; 3158 lm_status = lm_get_stats( pdev, stats_type, &val 3159 #ifdef VF_INVOLVED 3160 ,NULL 3161 #endif 3162 ) ; 3163 if ERR_IF( LM_STATUS_SUCCESS != lm_status ) 3164 { 3165 DbgMessage(pdev, WARNstat, "lm_stats_mcp_assign: lm_get_stats type=0x%X failed. lm_status=0x%X", stats_type, lm_status ) ; 3166 } 3167 else 3168 { 3169 val+= LM_STATS_HI_LO_TO_64(mcp_func_base->total_broadcast_packets_transmitted, val_base); 3170 mcp_func->total_broadcast_packets_transmitted_hi = (u32_t)U64_HI( val ) ; 3171 mcp_func->total_broadcast_packets_transmitted_lo = (u32_t)U64_LO( val ) ; 3172 } 3173 3174 // Calculate the size to be written through DMAE 3175 val = sizeof(pdev->vars.stats.stats_mirror.stats_mcp_func) ; 3176 val = val/sizeof(u32_t) ; 3177 mcp_func->host_func_stats_end = ++mcp_func->host_func_stats_start ; 3178 3179 // This code section must be under phy lock! 3180 REG_WR_DMAE_LEN(pdev, 3181 pdev->vars.fw_func_stats_ptr, 3182 mcp_func, 3183 (u16_t)val ) ; 3184 3185 } // lm_stats_mgmt_assign 3186 3187 /* 3188 *------------------------------------------------------------------------ 3189 * lm_stats_mgmt_read_base - 3190 * 3191 * read values from mgmt structures into host_func_stats_t base structure 3192 * this is as a basic value that will be added when function report statistics 3193 * NOTE: function must be called under PHY_LOCK (since it uses REG_RD_DMAE interface) 3194 *------------------------------------------------------------------------ 3195 */ 3196 static void lm_stats_mgmt_read_func_base( IN struct _lm_device_t* pdev ) 3197 { 3198 u64_t val = 0 ; 3199 host_func_stats_t* mcp_func_base = NULL ; 3200 3201 if CHK_NULL(pdev) 3202 { 3203 return; 3204 } 3205 3206 if( 0 == pdev->vars.fw_func_stats_ptr ) 3207 { 3208 return; 3209 } 3210 3211 if (GET_FLAGS(pdev->params.test_mode, TEST_MODE_NO_MCP )) 3212 { 3213 return; 3214 } 3215 3216 mcp_func_base = &pdev->vars.stats.stats_mirror.stats_mcp_func_base ; 3217 3218 val = sizeof(pdev->vars.stats.stats_mirror.stats_mcp_func_base) ; 3219 val = val/sizeof(u32_t) ; 3220 3221 // This code section must be under phy lock! 3222 REG_RD_DMAE_LEN(pdev, 3223 pdev->vars.fw_func_stats_ptr, 3224 mcp_func_base, 3225 (u16_t)val ) ; 3226 3227 } // lm_stats_mgmt_read_base 3228 3229 3230 /* 3231 *------------------------------------------------------------------------ 3232 * lm_stats_mgmt_clear_all_func - 3233 * 3234 * clear mgmt statistics for all function 3235 * should be called on init port part. first function should clear all other functions mail box 3236 * NOTE: function must be called under PHY_LOCK (since it uses REG_WR_DMAE interface) 3237 *------------------------------------------------------------------------ 3238 */ 3239 static void lm_stats_mgmt_clear_all_func( IN struct _lm_device_t* pdev ) 3240 { 3241 u64_t val = 0 ; 3242 u8_t func = 0; 3243 u32_t fw_func_stats_ptr = 0; 3244 3245 // use current pdev stats_mcp_func for all function - (zeroed buffer) 3246 val = sizeof(pdev->vars.stats.stats_mirror.stats_mcp_func); 3247 mm_mem_zero(&pdev->vars.stats.stats_mirror.stats_mcp_func, (u32_t)val ); 3248 3249 val = val/sizeof(u32_t) ; 3250 3251 LM_FOREACH_FUNC_MAILBOX_IN_PORT(pdev,func) 3252 { 3253 lm_setup_read_mgmt_stats_ptr(pdev, func, NULL, &fw_func_stats_ptr ); 3254 3255 if( 0 != fw_func_stats_ptr ) 3256 { 3257 3258 // This code section must be under phy lock! 3259 // writes zero 3260 REG_WR_DMAE_LEN(pdev, 3261 fw_func_stats_ptr, 3262 &pdev->vars.stats.stats_mirror.stats_mcp_func, 3263 (u16_t)val ) ; 3264 } 3265 if(CHIP_IS_E1(pdev) || (!CHIP_IS_E1x(pdev) && (CHIP_PORT_MODE(pdev) == LM_CHIP_PORT_MODE_4))) 3266 { 3267 // only one iteration functionand one for E1 ! 3268 break; 3269 } 3270 } 3271 } // lm_stats_mgmt_clear_all_func 3272 3273 /* 3274 *Function Name:lm_stats_port_to_from 3275 * 3276 *Parameters: 3277 * b_is_to - determine is it operation to/from MCP 3278 * b_is_to TRUE - to MCP 3279 * b_is_to FLASE - from MCP 3280 *Description: 3281 * Helper function in order to set stats to/from mcp to driver host when swithcing PMF's 3282 * 3283 *Returns: 3284 * 3285 */ 3286 void lm_stats_port_to_from( IN OUT struct _lm_device_t* pdev, u8_t b_is_to ) 3287 { 3288 host_port_stats_t* mcp_port = NULL ; 3289 lm_stats_hw_t* stats_hw = NULL ; 3290 stats_macs_idx_t stats_macs_idx = STATS_MACS_IDX_MAX ; 3291 u8_t i = 0 ; 3292 3293 mcp_port = &pdev->vars.stats.stats_mirror.stats_mcp_port ; 3294 stats_hw = &pdev->vars.stats.stats_mirror.stats_hw ; 3295 3296 ASSERT_STATIC( STATS_MACS_IDX_MAX == MAC_STX_IDX_MAX ); 3297 ASSERT_STATIC( STATS_MACS_IDX_CURRENT < STATS_MACS_IDX_TOTAL ); 3298 3299 3300 // B/EMAC is up: 3301 // OLD PMF: 3302 // copy all EMAC 'reset' to 'total' 3303 // 3304 // NEW PMF: 3305 // copy all EMAC 'total' to 'reset' 3306 // 3307 // NONE is up: 3308 // copy only 'reset' to 'total' 3309 3310 switch( pdev->vars.mac_type ) 3311 { 3312 case MAC_TYPE_EMAC: 3313 case MAC_TYPE_BMAC: 3314 case MAC_TYPE_UMAC: 3315 case MAC_TYPE_XMAC: 3316 stats_macs_idx = STATS_MACS_IDX_CURRENT ; 3317 break; 3318 3319 case MAC_TYPE_NONE: 3320 stats_macs_idx = STATS_MACS_IDX_TOTAL ; 3321 break; 3322 3323 default: 3324 DbgBreakMsg( "mac_type not acceptable" ) ; 3325 return; 3326 } 3327 3328 #define LM_STATS_PMF_TO_FROM( _mcp_field, _hw_field, _b_is_to ) \ 3329 if( _b_is_to )\ 3330 { \ 3331 LM_STATS_64_TO_HI_LO( stats_hw->macs[i]._hw_field, mcp_port->mac_stx[i]._mcp_field );\ 3332 } \ 3333 else \ 3334 { \ 3335 LM_STATS_HI_LO_TO_64( mcp_port->mac_stx[i]._mcp_field, stats_hw->macs[i]._hw_field ) ;\ 3336 } 3337 3338 3339 for( i = stats_macs_idx; i < STATS_MACS_IDX_MAX; i++ ) 3340 { 3341 LM_STATS_PMF_TO_FROM( rx_stat_dot3statsfcserrors, stats_rx.rx_stat_dot3statsfcserrors, b_is_to ) ; 3342 LM_STATS_PMF_TO_FROM( rx_stat_dot3statsalignmenterrors, stats_rx.rx_stat_dot3statsalignmenterrors, b_is_to ) ; // BMAC 0 3343 LM_STATS_PMF_TO_FROM( rx_stat_dot3statscarriersenseerrors, stats_rx.rx_stat_dot3statscarriersenseerrors, b_is_to ) ; // BMAC 0 3344 LM_STATS_PMF_TO_FROM( rx_stat_etherstatsundersizepkts, stats_rx.rx_stat_etherstatsundersizepkts, b_is_to ) ; 3345 3346 // Exception - don't migrate this parameter (mandatory NDIS parameter) 3347 //LM_STATS_PMF_TO_FROM( rx_stat_dot3statsframestoolong, stats_rx.rx_stat_dot3statsframestoolong, b_is_to ) ; 3348 3349 LM_STATS_PMF_TO_FROM( rx_stat_xonpauseframesreceived, stats_rx.rx_stat_xonpauseframesreceived, b_is_to ) ; // BMAC 0 3350 LM_STATS_PMF_TO_FROM( rx_stat_xoffpauseframesreceived, stats_rx.rx_stat_xoffpauseframesreceived, b_is_to ) ; 3351 LM_STATS_PMF_TO_FROM( tx_stat_outxonsent, stats_tx.tx_stat_outxonsent, b_is_to ) ; // BMAC 0 3352 LM_STATS_PMF_TO_FROM( tx_stat_outxoffsent, stats_tx.tx_stat_outxoffsent, b_is_to ) ; 3353 LM_STATS_PMF_TO_FROM( tx_stat_dot3statssinglecollisionframes, stats_tx.tx_stat_dot3statssinglecollisionframes, b_is_to ) ; // BMAC 0 3354 LM_STATS_PMF_TO_FROM( tx_stat_dot3statsmultiplecollisionframes, stats_tx.tx_stat_dot3statsmultiplecollisionframes, b_is_to ) ; // BMAC 0 3355 LM_STATS_PMF_TO_FROM( tx_stat_dot3statslatecollisions, stats_tx.tx_stat_dot3statslatecollisions, b_is_to ) ; // BMAC 0 3356 LM_STATS_PMF_TO_FROM( tx_stat_dot3statsexcessivecollisions, stats_tx.tx_stat_dot3statsexcessivecollisions, b_is_to ) ; // BMAC 0 3357 LM_STATS_PMF_TO_FROM( rx_stat_maccontrolframesreceived, stats_rx.rx_stat_maccontrolframesreceived, b_is_to ) ; 3358 3359 LM_STATS_PMF_TO_FROM( rx_stat_mac_xpf, stats_rx.rx_stat_maccontrolframesreceived_bmac_xpf, b_is_to ) ; // EMAC 0 BMAC only 3360 LM_STATS_PMF_TO_FROM( rx_stat_mac_xcf, stats_rx.rx_stat_maccontrolframesreceived_bmac_xcf, b_is_to ) ; // EMAC 0 BMAC only 3361 3362 LM_STATS_PMF_TO_FROM( tx_stat_etherstatspkts64octets, stats_tx.tx_stat_etherstatspkts64octets, b_is_to ) ; 3363 LM_STATS_PMF_TO_FROM( tx_stat_etherstatspkts65octetsto127octets, stats_tx.tx_stat_etherstatspkts65octetsto127octets, b_is_to ) ; 3364 LM_STATS_PMF_TO_FROM( tx_stat_etherstatspkts128octetsto255octets, stats_tx.tx_stat_etherstatspkts128octetsto255octets, b_is_to ) ; 3365 LM_STATS_PMF_TO_FROM( tx_stat_etherstatspkts256octetsto511octets, stats_tx.tx_stat_etherstatspkts256octetsto511octets, b_is_to ) ; 3366 LM_STATS_PMF_TO_FROM( tx_stat_etherstatspkts512octetsto1023octets, stats_tx.tx_stat_etherstatspkts512octetsto1023octets, b_is_to ) ; 3367 LM_STATS_PMF_TO_FROM( tx_stat_etherstatspkts1024octetsto1522octets, stats_tx.tx_stat_etherstatspkts1024octetsto1522octet, b_is_to ) ; 3368 LM_STATS_PMF_TO_FROM( tx_stat_etherstatspktsover1522octets, stats_tx.tx_stat_etherstatspktsover1522octets, b_is_to ) ; 3369 3370 3371 LM_STATS_PMF_TO_FROM( tx_stat_mac_2047, stats_tx.tx_stat_etherstatspktsover1522octets_bmac_2047, b_is_to ) ; // EMAC 0 BMAC only 3372 LM_STATS_PMF_TO_FROM( tx_stat_mac_4095, stats_tx.tx_stat_etherstatspktsover1522octets_bmac_4095, b_is_to ) ; // EMAC 0 BMAC only 3373 LM_STATS_PMF_TO_FROM( tx_stat_mac_9216, stats_tx.tx_stat_etherstatspktsover1522octets_bmac_9216, b_is_to ) ; // EMAC 0 BMAC only 3374 LM_STATS_PMF_TO_FROM( tx_stat_mac_16383, stats_tx.tx_stat_etherstatspktsover1522octets_bmac_16383, b_is_to ) ; // EMAC 0 BMAC only 3375 3376 LM_STATS_PMF_TO_FROM( rx_stat_etherstatsfragments, stats_rx.rx_stat_etherstatsfragments, b_is_to ) ; 3377 LM_STATS_PMF_TO_FROM( rx_stat_etherstatsjabbers, stats_rx.rx_stat_etherstatsjabbers, b_is_to ) ; 3378 LM_STATS_PMF_TO_FROM( tx_stat_dot3statsdeferredtransmissions, stats_tx.tx_stat_dot3statsdeferredtransmissions, b_is_to ) ; // BMAC 0 3379 LM_STATS_PMF_TO_FROM( tx_stat_dot3statsinternalmactransmiterrors, stats_tx.tx_stat_dot3statsinternalmactransmiterrors, b_is_to ) ; 3380 LM_STATS_PMF_TO_FROM( tx_stat_etherstatscollisions, stats_tx.tx_stat_etherstatscollisions, b_is_to ) ; // BMAC 0 3381 LM_STATS_PMF_TO_FROM( tx_stat_flowcontroldone, stats_tx.tx_stat_flowcontroldone, b_is_to ) ; 3382 LM_STATS_PMF_TO_FROM( rx_stat_xoffstateentered, stats_rx.rx_stat_xoffstateentered, b_is_to ) ; 3383 LM_STATS_PMF_TO_FROM( rx_stat_ifhcinbadoctets, stats_rx.rx_stat_ifhcinbadoctets, b_is_to ) ; 3384 LM_STATS_PMF_TO_FROM( tx_stat_ifhcoutbadoctets, stats_tx.tx_stat_ifhcoutbadoctets, b_is_to ) ; // BMAC 0 3385 LM_STATS_PMF_TO_FROM( tx_stat_mac_ufl, stats_tx.tx_stat_ifhcoutdiscards, b_is_to ) ; // EMAC 0 3386 LM_STATS_PMF_TO_FROM( rx_stat_dot3statscarriersenseerrors, stats_rx.rx_stat_dot3statscarriersenseerrors, b_is_to ) ; // BMAC 0 3387 } 3388 3389 // NIG, MSTAT and EEE 3390 if( b_is_to) 3391 { 3392 LM_STATS_64_TO_HI_LO( stats_hw->nig.brb_discard, mcp_port->brb_drop ) ; 3393 3394 LM_STATS_64_TO_HI_LO( stats_hw->macs->stats_tx.tx_stat_pfcPacketCounter, mcp_port->pfc_frames_tx ); 3395 LM_STATS_64_TO_HI_LO( stats_hw->macs->stats_rx.rx_stat_pfcPacketCounter, mcp_port->pfc_frames_rx ); 3396 3397 LM_STATS_64_TO_HI_LO( stats_hw->misc.tx_lpi_count, mcp_port->eee_lpi_count); 3398 } 3399 else 3400 { 3401 LM_STATS_HI_LO_TO_64( mcp_port->brb_drop, stats_hw->nig.brb_discard ) ; 3402 3403 LM_STATS_HI_LO_TO_64( mcp_port->pfc_frames_tx, stats_hw->macs->stats_tx.tx_stat_pfcPacketCounter ); 3404 LM_STATS_HI_LO_TO_64( mcp_port->pfc_frames_rx, stats_hw->macs->stats_rx.rx_stat_pfcPacketCounter ); 3405 3406 LM_STATS_HI_LO_TO_64( mcp_port->eee_lpi_count, stats_hw->misc.tx_lpi_count); 3407 } 3408 3409 } 3410 3411 /* 3412 * \brief Calculate MCP status port size 3413 * 3414 * Calculate the size to be written. 3415 * 3416 * This logic is required as b10_l2_chip_statistics_t may increase in size 3417 * (due to driver change), while MCP area reserved does not follow suit 3418 * (as is the case, for example, when the driver and MFW do not version- 3419 * match). 3420 * 3421 * This logic calculates the size available based on MFW version, and an 3422 * additional shmem item added to specifically report size available, thus 3423 * making future changes to statistics MCP size proof. 3424 * 3425 */ 3426 3427 STATIC u16_t lm_stats_port_size(IN struct _lm_device_t *pdev) 3428 { 3429 const u32_t bc_rev_major = LM_GET_BC_REV_MAJOR(pdev); 3430 const u8_t b_bc_pfc_support = bc_rev_major >= REQ_BC_VER_4_PFC_STATS_SUPPORTED; 3431 size_t sizeof_port_stats = 0; 3432 u32_t sizeof_port_satas_shmem = 0; 3433 3434 if (LM_SHMEM2_HAS(pdev,sizeof_port_stats)) 3435 { 3436 LM_SHMEM2_READ(pdev,OFFSETOF(struct shmem2_region, sizeof_port_stats), &sizeof_port_satas_shmem); 3437 3438 sizeof_port_stats = min((size_t)sizeof_port_satas_shmem, sizeof(pdev->vars.stats.stats_mirror.stats_mcp_port)); 3439 } 3440 else 3441 { 3442 if (b_bc_pfc_support) 3443 { 3444 // "pfc_frames_rx_lo" is the last member of host_port_stats_t for that MFW version. 3445 3446 sizeof_port_stats = OFFSETOF(host_port_stats_t, pfc_frames_rx_lo) + 3447 sizeof(pdev->vars.stats.stats_mirror.stats_mcp_port.pfc_frames_rx_lo); 3448 } 3449 else 3450 { 3451 // "not_used" is the last member of host_port_stats_t for that MFW version. 3452 3453 sizeof_port_stats = OFFSETOF(host_port_stats_t, not_used ) + 3454 sizeof(pdev->vars.stats.stats_mirror.stats_mcp_port.not_used); 3455 } 3456 } 3457 3458 sizeof_port_stats /= sizeof(u32_t) ; 3459 3460 /* 3461 * we are returning only 16 bits of the size calculated. Check (CHK version only) if the size 3462 * is too big to be held in 16 bits, which either indicate an error wrt size, or DMAE 3463 * about to be provided with a task too big. 3464 */ 3465 3466 DbgBreakIf( sizeof_port_stats >= 1u<<(sizeof(u16_t)*8) ); 3467 3468 return (u16_t)sizeof_port_stats; 3469 } 3470 3471 /* 3472 *Function Name:lm_stats_port_zero 3473 * 3474 *Parameters: 3475 * 3476 *Description: 3477 * This function should be called by first function on port (PMF) - zeros MCP scatrch pad 3478 *Returns: 3479 * 3480 */ 3481 lm_status_t lm_stats_port_zero( IN struct _lm_device_t* pdev ) 3482 { 3483 u16_t size = 0 ; 3484 lm_status_t lm_status = LM_STATUS_SUCCESS ; 3485 3486 if( 0 == pdev->vars.fw_port_stats_ptr ) 3487 { 3488 /* This could happen and therefore is not considered an error */ 3489 return LM_STATUS_SUCCESS; 3490 } 3491 3492 // Calculate the size to be written through DMAE 3493 size = lm_stats_port_size(pdev); 3494 3495 // This code section must be under phy lock! 3496 REG_WR_DMAE_LEN_ZERO(pdev, 3497 pdev->vars.fw_port_stats_ptr, 3498 size ) ; 3499 3500 return lm_status ; 3501 } 3502 3503 /* 3504 *Function Name:lm_stats_port_save 3505 * 3506 *Parameters: 3507 * 3508 *Description: 3509 * This function should be called before PMF is unloaded in order to preserve statitiscs for the next PMF 3510 * ASSUMPTION: function must be called under PHY_LOCK (since it uses REG_WR_DMAE interface) 3511 * ASSUMPTION: link can not change at this point and until PMF is down 3512 *Returns: 3513 * 3514 */ 3515 lm_status_t lm_stats_port_save( IN struct _lm_device_t* pdev ) 3516 { 3517 u16_t size = 0 ; 3518 lm_status_t lm_status = LM_STATUS_SUCCESS ; 3519 host_port_stats_t* mcp_port = NULL ; 3520 3521 if( 0 == pdev->vars.fw_port_stats_ptr ) 3522 { 3523 /* This could happen and therefore is not considered an error */ 3524 return LM_STATUS_SUCCESS; 3525 } 3526 3527 lm_stats_port_to_from( pdev, TRUE ) ; 3528 3529 // Calculate the size to be written through DMAE 3530 size = lm_stats_port_size(pdev); 3531 3532 mcp_port = &pdev->vars.stats.stats_mirror.stats_mcp_port ; 3533 mcp_port->not_used = ++mcp_port->host_port_stats_counter ; 3534 3535 // This code section must be under phy lock! 3536 REG_WR_DMAE_LEN(pdev, 3537 pdev->vars.fw_port_stats_ptr, 3538 mcp_port, 3539 size ) ; 3540 3541 return lm_status ; 3542 } 3543 3544 /* 3545 *Function Name:lm_stats_port_load 3546 * 3547 *Parameters: 3548 * 3549 *Description: 3550 * This function should be called before a new PMF is loaded in order to restore statitiscs from the previous PMF 3551 * vars.is_pmf should be set to TRUE only after this function completed! 3552 * ASSUMPTION: function must be called under PHY_LOCK (since it uses REG_RD_DMAE interface) 3553 * ASSUMPTION: link can not change at this point and until PMF is up 3554 *Returns: 3555 * 3556 */ 3557 lm_status_t lm_stats_port_load( IN struct _lm_device_t* pdev ) 3558 { 3559 u16_t size = 0 ; 3560 lm_status_t lm_status = LM_STATUS_SUCCESS ; 3561 host_port_stats_t* mcp_port = NULL ; 3562 3563 if( 0 == pdev->vars.fw_port_stats_ptr ) 3564 { 3565 /* This could happen and therefore is not considered an error */ 3566 return LM_STATUS_SUCCESS; 3567 } 3568 3569 // Calculate the size to be written through DMAE 3570 size = lm_stats_port_size(pdev); 3571 3572 mcp_port = &pdev->vars.stats.stats_mirror.stats_mcp_port ; 3573 mcp_port->not_used = ++mcp_port->host_port_stats_counter ; 3574 3575 // This code section must be under phy lock! 3576 REG_RD_DMAE_LEN(pdev, 3577 pdev->vars.fw_port_stats_ptr, 3578 mcp_port, 3579 size ) ; 3580 3581 lm_stats_port_to_from( pdev, FALSE ) ; 3582 3583 return lm_status ; 3584 } 3585 3586 /* 3587 *------------------------------------------------------------------------ 3588 * lm_stats_mgmt_assign 3589 * 3590 * write values from mgmt structures into func and port base structure 3591 * NOTE: function must be called under PHY_LOCK (since it uses REG_RD_DMAE interface) 3592 *------------------------------------------------------------------------ 3593 */ 3594 void lm_stats_mgmt_assign( IN struct _lm_device_t* pdev ) 3595 { 3596 if CHK_NULL(pdev) 3597 { 3598 return; 3599 } 3600 3601 if ( GET_FLAGS(pdev->params.test_mode, TEST_MODE_NO_MCP ) ) 3602 { 3603 return; 3604 } 3605 3606 if( pdev->vars.fw_func_stats_ptr ) 3607 { 3608 lm_stats_mgmt_assign_func(pdev); 3609 } 3610 if( pdev->vars.fw_port_stats_ptr ) 3611 { 3612 // only PMF should assign port statistics 3613 if( IS_PMF(pdev) ) 3614 { 3615 lm_stats_port_save(pdev); 3616 } 3617 } 3618 } 3619 3620 /* 3621 *Function Name:lm_stats_on_pmf_update 3622 * 3623 *Parameters: 3624 * b_on: 3625 * TRUE - the device is beocming now a PMF 3626 * FALSE - the device is now going down and transfering PMF to another device 3627 *Description: 3628 * the function should be called under PHY LOCK. 3629 * TRUE when a device becoming a PMF and before the link status changed from last state when previous PMF was down after call for mcp driver load 3630 * FALSE when a device going down and after the link status saved and can not be changed (interrupts are disabled) before call for mcp driver unload 3631 *Returns: 3632 * 3633 */ 3634 lm_status_t lm_stats_on_pmf_update( struct _lm_device_t* pdev, IN u8_t b_on ) 3635 { 3636 lm_status_t lm_status = LM_STATUS_SUCCESS ; 3637 3638 if CHK_NULL(pdev) 3639 { 3640 return LM_STATUS_INVALID_PARAMETER; 3641 } 3642 3643 if( b_on ) 3644 { 3645 lm_status = lm_stats_port_load( pdev ); 3646 } 3647 else 3648 { 3649 lm_status = lm_stats_on_update_state(pdev); 3650 3651 // check for success, but link down is a valid situation! 3652 DbgBreakIf( ( LM_STATUS_SUCCESS != lm_status ) && ( LM_STATUS_LINK_DOWN != lm_status ) ); 3653 3654 // we need to save port stats only if link is down 3655 // if link is up, it was already made on call to lm_stats_on_update_state. 3656 if( LM_STATUS_LINK_DOWN == lm_status ) 3657 { 3658 lm_status = lm_stats_port_save( pdev ); 3659 } 3660 } 3661 return lm_status ; 3662 } 3663 /* 3664 *Function Name:lm_stats_on_pmf_init 3665 * 3666 *Parameters: 3667 * 3668 *Description: 3669 * call this function under PHY LOCK when FIRST ever PMF is on 3670 *Returns: 3671 * 3672 */ 3673 lm_status_t lm_stats_on_pmf_init( struct _lm_device_t* pdev ) 3674 { 3675 lm_status_t lm_status = LM_STATUS_SUCCESS ; 3676 if CHK_NULL(pdev) 3677 { 3678 return LM_STATUS_INVALID_PARAMETER; 3679 } 3680 3681 lm_status = lm_stats_port_zero( pdev ) ; 3682 3683 return lm_status ; 3684 3685 } 3686 3687 lm_status_t lm_stats_hw_collect( struct _lm_device_t* pdev ) 3688 { 3689 lm_status_t lm_status = LM_STATUS_SUCCESS; 3690 u8_t port = PORT_ID(pdev); 3691 const u32_t pkt0 = port ? NIG_REG_STAT1_EGRESS_MAC_PKT0 : NIG_REG_STAT0_EGRESS_MAC_PKT0 ; 3692 const u32_t pkt1 = port ? NIG_REG_STAT1_EGRESS_MAC_PKT1 : NIG_REG_STAT0_EGRESS_MAC_PKT1 ; 3693 const u32_t eee = port ? MISC_REG_CPMU_LP_SM_ENT_CNT_P1 : MISC_REG_CPMU_LP_SM_ENT_CNT_P0 ; 3694 3695 // call the dmae commands sequance 3696 lm_status = lm_stats_dmae( pdev ) ; 3697 if( LM_STATUS_SUCCESS != lm_status ) 3698 { 3699 return lm_status; 3700 } 3701 3702 // read two more NIG registers in the regular way - on E3 these do not exist!!! 3703 if (!CHIP_IS_E3(pdev)) 3704 { 3705 REG_RD_DMAE( pdev, pkt0, &pdev->vars.stats.stats_collect.stats_hw.nig_ex_stats_query.egress_mac_pkt0 ); 3706 REG_RD_DMAE( pdev, pkt1, &pdev->vars.stats.stats_collect.stats_hw.nig_ex_stats_query.egress_mac_pkt1 ); 3707 } 3708 3709 // EEE is only supported in E3 chip 3710 if (CHIP_IS_E3(pdev)) 3711 { 3712 pdev->vars.stats.stats_collect.stats_hw.misc_stats_query.tx_lpi_count = REG_RD(pdev, eee); 3713 } 3714 3715 return lm_status ; 3716 } 3717 3718 /* 3719 *Function Name:lm_stats_init_port_part 3720 * 3721 *Parameters: 3722 * 3723 *Description: 3724 * call this function under PHY LOCK on port init 3725 *Returns: 3726 * 3727 */ 3728 void lm_stats_init_port_part( struct _lm_device_t* pdev ) 3729 { 3730 lm_stats_mgmt_clear_all_func(pdev); 3731 } 3732 3733 /* 3734 *Function Name:lm_stats_init_port_part 3735 * 3736 *Parameters: 3737 * 3738 *Description: 3739 * call this function under PHY LOCK on function init 3740 *Returns: 3741 * 3742 */ 3743 void lm_stats_init_func_part( struct _lm_device_t* pdev ) 3744 { 3745 if (IS_PMF(pdev) && IS_MULTI_VNIC(pdev)) 3746 { 3747 lm_stats_on_pmf_init(pdev); 3748 } 3749 lm_stats_mgmt_read_func_base(pdev); 3750 } 3751