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 * 01/10/10 Shay Haroush Inception. 38 ******************************************************************************/ 39 40 #include "lm5710.h" 41 #include "license.h" 42 #include "mcp_shmem.h" 43 #include "577xx_int_offsets.h" 44 #include "command.h" 45 46 47 #define DCBX_ILLEGAL_PG (0xFF) 48 typedef struct _pg_entry_help_data_t 49 { 50 u8_t num_of_dif_pri; 51 u8_t pg; 52 u32_t pg_priority; 53 }pg_entry_help_data_t; 54 55 typedef struct _pg_help_data_t 56 { 57 pg_entry_help_data_t pg_entry_data[LLFC_DRIVER_TRAFFIC_TYPE_MAX]; 58 u8_t num_of_pg; 59 }pg_help_data_t; 60 61 // Used for IE classification debugging 62 typedef struct _lm_dcbx_ie_classif_dbg_t 63 { 64 u16_t pri; 65 u8_t num_entries; 66 }lm_dcbx_ie_classif_dbg_t; 67 68 #define DCBX_INVALID_COS_BW (0xFFFFFFFF) 69 #define DCBX_MAX_COS_BW (0xFF) 70 71 72 #define DCBX_MIB_IS_APP_ENABLED(_app_en,_mib_error_filed) \ 73 ((TRUE == _app_en) && \ 74 (!GET_FLAGS(_mib_error_filed,(DCBX_LOCAL_APP_ERROR| DCBX_LOCAL_APP_MISMATCH)))) 75 76 #define DCBX_MIB_IS_ETS_ENABLED(_app_en,_mib_error_filed,_mib_ets_en_filed) \ 77 ((TRUE == _app_en)&& \ 78 (!GET_FLAGS(_mib_error_filed,DCBX_LOCAL_ETS_ERROR))&& \ 79 _mib_ets_en_filed) 80 81 #define DCBX_MIB_IS_PFC_ENABLED(_app_en,_mib_error_filed,_mib_pfc_en_filed) \ 82 ((TRUE == _app_en)&& \ 83 (!GET_FLAGS(_mib_error_filed,(DCBX_LOCAL_PFC_ERROR | DCBX_LOCAL_PFC_MISMATCH)))&& \ 84 _mib_pfc_en_filed) 85 86 87 typedef struct _cos_entry_help_data_t 88 { 89 u32_t pri_join_mask; 90 u32_t cos_bw; 91 u8_t s_pri; 92 u8_t b_pausable; 93 }cos_entry_help_data_t; 94 95 typedef struct _cos_help_data_t 96 { 97 cos_entry_help_data_t entry_data[DCBX_COS_MAX_NUM]; 98 u8_t num_of_cos; 99 }cos_help_data_t; 100 101 /**********************foreword declaration************************************/ 102 /** 103 * @description 104 * Function is needed for PMF migration in order to synchronize 105 * the new PMF that DCBX results has ended. 106 * @param pdev 107 * 108 * @return u8_t 109 * This function returns TRUE if DCBX completion received on 110 * this port 111 */ 112 STATIC u8_t 113 lm_dcbx_check_drv_flags( 114 IN struct _lm_device_t *pdev, 115 IN const u32_t flags_bits_to_check); 116 117 /******************************************************************************* 118 * Description: Parse ets_pri_pg data and spread it from nibble to 32 bits. 119 * 120 * Return: 121 ******************************************************************************/ 122 STATIC void 123 lm_dcbx_get_ets_pri_pg_tbl(struct _lm_device_t * pdev, 124 OUT u32_t * set_configuration_ets_pg, 125 IN const u32_t * mcp_pri_pg_tbl, 126 IN const u8_t set_priority_app_size, 127 IN const u8_t mcp_pri_pg_tbl_size); 128 129 130 void lm_dcbx_update_lpme_set_params(struct _lm_device_t *pdev); 131 132 STATIC void 133 lm_dcbx_ie_ets_cee_to_ieee_unparse( 134 INOUT lm_device_t *pdev, 135 IN const dcbx_ets_feature_t *cee_ets, 136 OUT dcb_ets_tsa_param_t *ieee_ets, 137 OUT u32_t *flags 138 ); 139 140 STATIC lm_status_t 141 lm_dcbx_read_admin_mib( IN lm_device_t *pdev, 142 OUT lldp_admin_mib_t *p_admin_mib, 143 OUT u32_t *p_admin_mib_offset); 144 145 /**********************Start of PFC code**************************************/ 146 147 /** 148 * Check if DCB is configured. 149 * In SF is_dcbx_neg_received is always valid. 150 * DRV_FLAGS_DCB_CONFIGURED is always valid. 151 * @param pdev 152 * 153 * @return u8_t 154 */ 155 u8_t 156 lm_dcbx_is_dcb_config(IN lm_device_t *pdev) 157 { 158 // Valid in SF 159 u8_t const dcb_config_sf = pdev->dcbx_info.is_dcbx_neg_received; 160 // Always valid. 161 u8_t const dcb_config = lm_dcbx_check_drv_flags(pdev, DRV_FLAGS_DCB_CONFIGURED); 162 163 if(FALSE == IS_MULTI_VNIC(pdev)) 164 { 165 DbgBreakIf(dcb_config != dcb_config_sf); 166 } 167 168 return dcb_config; 169 } 170 /******************************************************************************* 171 * Description: Fill Fw struct that will be sent in DCBX start ramrod 172 * 173 * Return: 174 ******************************************************************************/ 175 void 176 lm_dcbx_print_cos_params( 177 IN OUT lm_device_t *pdev, 178 IN struct flow_control_configuration *pfc_fw_cfg) 179 { 180 #if DBG 181 u8_t pri = 0; 182 u8_t cos = 0; 183 184 DbgMessage(pdev, INFORM, "******************DCBX configuration******************************\n"); 185 DbgMessage(pdev, INFORM, "pfc_fw_cfg->dcb_version %x\n",pfc_fw_cfg->dcb_version); 186 DbgMessage(pdev, INFORM, "pdev->params.dcbx_port_params.pfc.priority_non_pauseable_mask %x\n", 187 pdev->params.dcbx_port_params.pfc.priority_non_pauseable_mask); 188 189 for( cos =0 ; cos < pdev->params.dcbx_port_params.ets.num_of_cos ; cos++) 190 { 191 DbgMessage(pdev, INFORM, "pdev->params.dcbx_port_params.ets.cos_params[%d].pri_bitmask %x\n",cos, 192 pdev->params.dcbx_port_params.ets.cos_params[cos].pri_bitmask); 193 194 DbgMessage(pdev, INFORM, "pdev->params.dcbx_port_params.ets.cos_params[%d].bw_tbl %x\n",cos, 195 pdev->params.dcbx_port_params.ets.cos_params[cos].bw_tbl); 196 197 DbgMessage(pdev, INFORM, "pdev->params.dcbx_port_params.ets.cos_params[%d].strict %x\n",cos, 198 pdev->params.dcbx_port_params.ets.cos_params[cos].s_pri); 199 200 DbgMessage(pdev, INFORM, "pdev->params.dcbx_port_params.ets.cos_params[%d].pauseable %x\n",cos, 201 pdev->params.dcbx_port_params.ets.cos_params[cos].pauseable); 202 } 203 204 for (pri = 0; pri < ARRSIZE(pdev->params.dcbx_port_params.app.traffic_type_priority); pri++) 205 { 206 DbgMessage(pdev, INFORM, "pfc_fw_cfg->traffic_type_to_priority_cos[%d].priority %x\n",pri, 207 pfc_fw_cfg->traffic_type_to_priority_cos[pri].priority); 208 209 DbgMessage(pdev, INFORM, "pfc_fw_cfg->traffic_type_to_priority_cos[%d].cos %x\n",pri, 210 pfc_fw_cfg->traffic_type_to_priority_cos[pri].cos); 211 } 212 213 #endif //DBG 214 } 215 /******************************************************************************* 216 * Description: Fill Fw struct that will be sent in DCBX start ramrod 217 * 218 * Return: 219 ******************************************************************************/ 220 void 221 lm_dcbx_fw_struct( 222 IN OUT lm_device_t *pdev) 223 { 224 struct flow_control_configuration *pfc_fw_cfg = NULL; 225 u16_t pri_bit = 0; 226 u8_t cos = 0; 227 u8_t pri = 0; 228 229 if(CHK_NULL(pdev->dcbx_info.pfc_fw_cfg_virt)) 230 { 231 DbgBreakMsg("lm_pfc_fw_struct_e2:pfc_fw_cfg_virt was not allocated DCBX should have been disabled "); 232 return; 233 } 234 pfc_fw_cfg = (struct flow_control_configuration*)pdev->dcbx_info.pfc_fw_cfg_virt; 235 mm_mem_zero(pfc_fw_cfg, sizeof(struct flow_control_configuration)); 236 237 pfc_fw_cfg->dcb_version = 0; // Reserved field 238 239 // If priority tagging (app ID) isn't enabled then DCB should be disabled. 240 if(FALSE == pdev->params.dcbx_port_params.app.enabled) 241 { 242 // Disabled DCB at FW. 243 pfc_fw_cfg->dcb_enabled = 0; 244 return; 245 } 246 247 DbgBreakIf(FALSE == pdev->params.dcbx_port_params.dcbx_enabled); 248 249 // Enable priority tagging and DCB at FW 250 pfc_fw_cfg->dcb_enabled = 1; 251 pfc_fw_cfg->dont_add_pri_0 = 1; 252 253 // Default initialization 254 for (pri = 0; pri < ARRSIZE(pfc_fw_cfg->traffic_type_to_priority_cos) ; pri++) 255 { 256 pfc_fw_cfg->traffic_type_to_priority_cos[pri].priority = LLFC_TRAFFIC_TYPE_TO_PRIORITY_UNMAPPED; 257 pfc_fw_cfg->traffic_type_to_priority_cos[pri].cos = 0; 258 } 259 260 // Fill priority parameters 261 for (pri = 0; pri < ARRSIZE(pdev->params.dcbx_port_params.app.traffic_type_priority); pri++) 262 { 263 DbgBreakIf(pdev->params.dcbx_port_params.app.traffic_type_priority[pri] >= MAX_PFC_PRIORITIES); 264 pfc_fw_cfg->traffic_type_to_priority_cos[pri].priority = 265 (u8_t)pdev->params.dcbx_port_params.app.traffic_type_priority[pri]; 266 267 pri_bit = 1 << pfc_fw_cfg->traffic_type_to_priority_cos[pri].priority; 268 // Fill COS parameters based on COS calculated to make it more generally for future use 269 for( cos =0 ; cos < pdev->params.dcbx_port_params.ets.num_of_cos ; cos++) 270 { 271 if (pdev->params.dcbx_port_params.ets.cos_params[cos].pri_bitmask & pri_bit) 272 { 273 pfc_fw_cfg->traffic_type_to_priority_cos[pri].cos = cos; 274 } 275 } 276 } 277 lm_dcbx_print_cos_params(pdev, 278 pfc_fw_cfg); 279 280 } 281 /******************************************************************************* 282 * Description: 283 * 284 * Return: 285 ******************************************************************************/ 286 static void 287 lm_pfc_clear(lm_device_t *pdev) 288 { 289 u8_t elink_status = ELINK_STATUS_OK; 290 291 MM_ACQUIRE_PHY_LOCK(pdev); 292 RESET_FLAGS(pdev->params.link.feature_config_flags, ELINK_FEATURE_CONFIG_PFC_ENABLED); 293 elink_status = elink_update_pfc(&pdev->params.link, &pdev->vars.link, 0); 294 DbgBreakIf(ELINK_STATUS_OK != elink_status); 295 MM_RELEASE_PHY_LOCK(pdev); 296 } 297 /******************************************************************************* 298 * Description: 299 * 300 * Return: 301 ******************************************************************************/ 302 static void lm_pfc_set_clc(lm_device_t *pdev) 303 { 304 struct elink_nig_brb_pfc_port_params pfc_params = {0}; 305 pg_params_t *ets = &pdev->params.dcbx_port_params.ets; 306 u32_t val = 0; 307 u32_t pri_bit = 0; 308 u8_t i = 0; 309 u8_t elink_status = ELINK_STATUS_OK; 310 const u32_t class_rx_pause = 0; 311 const u32_t class_rx_nonpause = 1; 312 313 DbgBreakIf(class_rx_pause == class_rx_nonpause); 314 DbgBreakIf((0 != class_rx_pause) && (1 != class_rx_pause)); 315 DbgBreakIf((0 != class_rx_nonpause) && (1 != class_rx_nonpause)); 316 317 // Tx COS configuration 318 // Here COS == pri 319 pfc_params.num_of_rx_cos_priority_mask = ets->num_of_cos; 320 321 for(i = 0 ; i < ets->num_of_cos ; i++) 322 { 323 // We configured in this register only the pause-able bits.(non pause-able aren't configure at all) 324 // it is done to avoid false pauses from network. 325 pfc_params.rx_cos_priority_mask[i] = 326 ets->cos_params[i].pri_bitmask & LM_DCBX_PFC_PRI_PAUSE_MASK(pdev); 327 } 328 329 // Rx COS configuration 330 // Changing PFC RX configuration . In RX COS0 will always be configured to lossless 331 // and COS1 to lossy. 332 // Here i == pri 333 for(i = 0 ; i < MAX_PFC_PRIORITIES ; i++) 334 { 335 pri_bit = 1 << i; 336 337 if(pri_bit & LM_DCBX_PFC_PRI_PAUSE_MASK(pdev)) 338 { 339 val |= class_rx_pause << (i * 4); 340 } 341 else 342 { 343 val |= class_rx_nonpause << (i * 4); 344 } 345 } 346 347 pfc_params.pkt_priority_to_cos = val; 348 349 if(0 == class_rx_pause) 350 { 351 // RX Classs0: On BRB class0 trigger PFC TX. Classes are low-priority for port #. When PFC is triggered on class 0 send PFC with this priorities to stop 352 pfc_params.llfc_low_priority_classes = LM_DCBX_PFC_PRI_PAUSE_MASK(pdev); 353 // RX Classs1: On BRB class1 trigger PFC TX. Classes are low-priority for port #. When PFC is triggered on class 1 send PFC with this priorities to stop 354 pfc_params.llfc_high_priority_classes = 0; 355 } 356 else 357 { 358 DbgBreakIf(1 != class_rx_pause); 359 pfc_params.llfc_low_priority_classes = 0; 360 pfc_params.llfc_high_priority_classes = LM_DCBX_PFC_PRI_PAUSE_MASK(pdev); 361 } 362 363 MM_ACQUIRE_PHY_LOCK(pdev); 364 SET_FLAGS(pdev->params.link.feature_config_flags, ELINK_FEATURE_CONFIG_PFC_ENABLED); 365 elink_status = elink_update_pfc(&pdev->params.link, &pdev->vars.link, &pfc_params); 366 DbgBreakIf(ELINK_STATUS_OK != elink_status); 367 MM_RELEASE_PHY_LOCK(pdev); 368 } 369 /******************************************************************************* 370 * Description: 371 * 372 * Return: 373 ******************************************************************************/ 374 void 375 lm_pfc_set_pfc( 376 lm_device_t *pdev) 377 { 378 DbgBreakIf(CHIP_IS_E1x(pdev)); 379 //1. Fills up common PFC structures if required. 380 //2. Configure BRB 381 //3. Configure NIG. 382 //4. Configure the MAC via the CLC: 383 //" CLC must first check if BMAC is not in reset and only then configures the BMAC 384 //" Or, configure EMAC. 385 lm_pfc_set_clc(pdev); 386 } 387 388 /******************************************************************************* 389 * Description: 390 * 391 * Return: 392 ******************************************************************************/ 393 void 394 lm_pfc_handle_pfc( 395 lm_device_t *pdev) 396 { 397 DbgBreakIf(CHIP_IS_E1x(pdev)); 398 // Only for testing DCBX client the registry key won't be 0 or 1 399 // Only a call from lm_chip_init can be not 0 or 1 400 if(TRUE == pdev->params.dcbx_port_params.pfc.enabled) 401 {// PFC enabled 402 lm_pfc_set_pfc(pdev); 403 } 404 else 405 {// PFC disabled go back to pause if needed 406 lm_pfc_clear(pdev); 407 } 408 } 409 410 void 411 lm_dcbx_2cos_limit_update_ets_config( 412 lm_device_t *pdev) 413 { 414 415 pg_params_t *ets = &(pdev->params.dcbx_port_params.ets); 416 u8_t elink_status = ELINK_STATUS_OK; 417 u32_t bw_tbl_0 = 0; 418 u32_t bw_tbl_1 = 0; 419 420 if ((0 == ets->num_of_cos ) || 421 (DCBX_COS_MAX_NUM_E2E3A0 < ets->num_of_cos)) 422 { 423 DbgMessage(pdev, FATAL, " illegal num of cos= %x",ets->num_of_cos); 424 DbgBreakIf(1); 425 return; 426 } 427 //valid COS entries 428 if( 1 == ets->num_of_cos) 429 {// No ETS 430 return; 431 } 432 DbgBreakIf(2 != ets->num_of_cos); 433 434 if(((DCBX_S_PRI_INVALID == ets->cos_params[0].s_pri)&& 435 (DCBX_INVALID_COS_BW == ets->cos_params[0].bw_tbl)) || 436 ((DCBX_S_PRI_INVALID == ets->cos_params[1].s_pri)&& 437 (DCBX_INVALID_COS_BW == ets->cos_params[1].bw_tbl))) 438 { 439 DbgMessage(pdev, FATAL, "We expect all the COS to have at least bw_limit or strict" 440 "ets->cos_params[0].strict= %x" 441 "ets->cos_params[0].bw_tbl= %x" 442 "ets->cos_params[1].strict= %x" 443 "ets->cos_params[1].bw_tbl= %x" 444 ,ets->cos_params[0].s_pri, ets->cos_params[0].bw_tbl 445 ,ets->cos_params[1].s_pri, ets->cos_params[1].bw_tbl); 446 447 // CQ47518,CQ47504 Assert in the eVBD because of illegal ETS parameters reception. When 448 //switch changes configuration in runtime it sends several packets that 449 //contain illegal configuration until the actual configuration is merged. 450 //DbgBreakIf(1); 451 return; 452 } 453 // If we join a group and there is bw_tbl and strict then bw rules. 454 if ((DCBX_INVALID_COS_BW != ets->cos_params[0].bw_tbl) && 455 (DCBX_INVALID_COS_BW != ets->cos_params[1].bw_tbl)) 456 { 457 DbgBreakIf(0 == (ets->cos_params[0].bw_tbl + ets->cos_params[1].bw_tbl)); 458 // ETS 0 100 PBF bug. 459 bw_tbl_0 = ets->cos_params[0].bw_tbl; 460 bw_tbl_1 = ets->cos_params[1].bw_tbl; 461 462 if((0 == bw_tbl_0)|| 463 (0 == bw_tbl_1)) 464 { 465 if(0 == bw_tbl_0) 466 { 467 bw_tbl_0 = 1; 468 bw_tbl_1 = 99; 469 } 470 else 471 { 472 bw_tbl_0 = 99; 473 bw_tbl_1 = 1; 474 } 475 476 } 477 // The priority is assign as BW 478 ets->cos_params[0].s_pri = DCBX_S_PRI_INVALID; 479 ets->cos_params[1].s_pri = DCBX_S_PRI_INVALID; 480 elink_ets_bw_limit(&pdev->params.link, 481 bw_tbl_0, 482 bw_tbl_1); 483 } 484 else 485 { 486 ets->cos_params[0].bw_tbl = DCBX_INVALID_COS_BW; 487 ets->cos_params[1].bw_tbl = DCBX_INVALID_COS_BW; 488 // The priority is assign as Strict 489 DbgBreakIf(ets->cos_params[0].s_pri == ets->cos_params[1].s_pri); 490 if(DCBX_S_PRI_COS_HIGHEST == ets->cos_params[0].s_pri) 491 { 492 ets->cos_params[1].s_pri = 493 DCBX_S_PRI_COS_NEXT_LOWER_PRI(DCBX_S_PRI_COS_HIGHEST); 494 elink_status = elink_ets_strict(&pdev->params.link,0); 495 } 496 else if(DCBX_S_PRI_COS_HIGHEST == ets->cos_params[1].s_pri) 497 { 498 ets->cos_params[0].s_pri = 499 DCBX_S_PRI_COS_NEXT_LOWER_PRI(DCBX_S_PRI_COS_HIGHEST); 500 elink_status = elink_ets_strict(&pdev->params.link,1); 501 } 502 503 if(ELINK_STATUS_OK != elink_status) 504 { 505 DbgBreakMsg("lm_dcbx_update_ets_params: elinc_ets_strict failed "); 506 } 507 } 508 } 509 /** 510 * @description 511 * Set ETS configuration in E3B0. 512 * In E3B0 the configuration may have more than 2 COS. 513 * @param pdev 514 */ 515 void 516 lm_dcbx_update_ets_config( 517 IN lm_device_t *pdev) 518 { 519 pg_params_t *ets = &(pdev->params.dcbx_port_params.ets); 520 struct elink_ets_params ets_params = {0}; 521 u8_t elink_status = ELINK_STATUS_OK; 522 u8_t i = 0; 523 524 ets_params.num_of_cos = ets->num_of_cos; 525 526 for(i = 0 ; i < ets->num_of_cos; i++) 527 { 528 if(DCBX_S_PRI_INVALID != ets->cos_params[i].s_pri) 529 {// COS is SP 530 if(DCBX_INVALID_COS_BW != ets->cos_params[i].bw_tbl) 531 { 532 DbgBreakMsg("lm_dcbx_update_ets_e3b0_params :COS can't be not BW and not SP"); 533 return; 534 } 535 ets_params.cos[i].state = elink_cos_state_strict; 536 ets_params.cos[i].params.sp_params.pri = ets->cos_params[i].s_pri; 537 } 538 else 539 {// COS is BW 540 if(DCBX_INVALID_COS_BW == ets->cos_params[i].bw_tbl) 541 { 542 DbgBreakMsg("lm_dcbx_update_ets_e3b0_params :COS can't be not BW and not SP"); 543 return; 544 } 545 ets_params.cos[i].state = elink_cos_state_bw; 546 ets_params.cos[i].params.bw_params.bw = (u8_t)ets->cos_params[i].bw_tbl; 547 } 548 549 } 550 551 // Configure the ETS in HW. 552 elink_status = elink_ets_e3b0_config(&pdev->params.link, 553 &pdev->vars.link, 554 &ets_params); 555 556 if(ELINK_STATUS_OK != elink_status) 557 { 558 DbgBreakMsg("lm_dcbx_update_ets_e3b0_params: ets_e3b0_config failed "); 559 elink_status = elink_ets_disabled(&pdev->params.link, 560 &pdev->vars.link); 561 } 562 } 563 /******************************************************************************* 564 * Description: 565 * 566 * Return: 567 ******************************************************************************/ 568 void 569 lm_dcbx_update_ets_params( 570 IN lm_device_t *pdev) 571 { 572 pg_params_t *ets = &(pdev->params.dcbx_port_params.ets); 573 u8_t elink_status = ELINK_STATUS_OK; 574 575 elink_status = elink_ets_disabled(&pdev->params.link, 576 &pdev->vars.link); 577 578 if(ELINK_STATUS_OK != elink_status) 579 { 580 DbgBreakMsg("lm_dcbx_update_ets_params the function elink_ets_disabled failed"); 581 return; 582 } 583 584 if(FALSE == ets->enabled) 585 { 586 return; 587 } 588 589 if(CHIP_IS_E3B0(pdev)) 590 { 591 lm_dcbx_update_ets_config(pdev); 592 } 593 else 594 { 595 DbgBreakIf(FALSE == CHIP_IS_E2E3A0(pdev)); 596 lm_dcbx_2cos_limit_update_ets_config(pdev); 597 } 598 599 } 600 /**********************End of PFC code**************************************/ 601 /**********************start DCBX Common FUNCTIONS**************************************/ 602 #define ETH_TYPE_FCOE (0x8906) 603 #define TCP_PORT_ISCSI (0xCBC) 604 605 606 /******************************************************************************* 607 * Description: 608 * Runtime changes can take more than 1 second and can't be handled 609 * from DPC. 610 * When the PMF detects a DCBX update it will schedule a WI that 611 * will handle the job. 612 * Also the function lm_dcbx_stop_HW_TX/lm_dcbx_resume_HW_TX must be 613 * called in mutual exclusion. 614 * lm_mcp_cmd_send_recieve must be called from default DPC, so when the 615 * WI will finish the processing an interrupt that will be called from 616 * The WI will cause us to enter this function again and send the Ack. 617 * 618 * Return: 619 ******************************************************************************/ 620 void 621 lm_dcbx_event(lm_device_t *pdev, 622 u32_t drv_status) 623 { 624 625 u32_t fw_resp = 0; 626 lm_status_t lm_status = LM_STATUS_SUCCESS ; 627 628 if(IS_PMF(pdev)) 629 { 630 if( GET_FLAGS( drv_status, DRV_STATUS_DCBX_NEGOTIATION_RESULTS)) 631 { 632 switch(pdev->dcbx_info.dcbx_update_lpme_task_state) 633 { 634 case DCBX_UPDATE_TASK_STATE_FREE: 635 // free: this is the first time we saw 636 // this DRV_STATUS_DCBX_NEGOTIATION_RES 637 if(FALSE == IS_DCB_ENABLED(pdev)) 638 { 639 return; 640 } 641 pdev->dcbx_info.dcbx_update_lpme_task_state = 642 DCBX_UPDATE_TASK_STATE_SCHEDULE; 643 lm_status = MM_REGISTER_LPME(pdev, 644 lm_dcbx_update_lpme_set_params, 645 TRUE, 646 FALSE);// DCBX sends ramrods 647 648 if (LM_STATUS_SUCCESS != lm_status) 649 { 650 pdev->dcbx_info.dcbx_update_lpme_task_state = 651 DCBX_UPDATE_TASK_STATE_FREE; 652 if(LM_STATUS_REQUEST_NOT_ACCEPTED == lm_status) 653 {// DCBX MM_REGISTER_LPME can fail 654 pdev->dcbx_info.lpme_failed_cnt++; 655 return; 656 } 657 pdev->dcbx_info.dcbx_error |= DCBX_ERROR_REGISTER_LPME; 658 // No rollback 659 // Problem because we won't get to DCBX_UPDATE_TASK_STATE_HANDLED (we won't schedule an interrupt) 660 DbgBreakMsg("lm_dcbx_int : The chip QM queues are stuck until an interrupt from MCP"); 661 //Free the MCP 662 lm_status = lm_mcp_cmd_send_recieve( pdev, 663 lm_mcp_mb_header, 664 DRV_MSG_CODE_DCBX_PMF_DRV_OK, 665 0, 666 MCP_CMD_DEFAULT_TIMEOUT, 667 &fw_resp ) ; 668 669 DbgBreakIf( lm_status != LM_STATUS_SUCCESS ); 670 671 } 672 break; 673 674 case DCBX_UPDATE_TASK_STATE_SCHEDULE: 675 // Schedule: We saw before that DRV_STATUS_DCBX_NEGOTIATION_RES 676 // is set before, and didn�t handle it yet 677 break; 678 679 case DCBX_UPDATE_TASK_STATE_HANDLED: 680 // handled: the WI handled was handled ,The MCP needs to updated 681 pdev->dcbx_info.dcbx_update_lpme_task_state = 682 DCBX_UPDATE_TASK_STATE_FREE; 683 684 lm_status = lm_mcp_cmd_send_recieve( pdev, 685 lm_mcp_mb_header, 686 DRV_MSG_CODE_DCBX_PMF_DRV_OK, 687 0, 688 MCP_CMD_DEFAULT_TIMEOUT, 689 &fw_resp ) ; 690 691 DbgBreakIf( lm_status != LM_STATUS_SUCCESS ); 692 break; 693 default: 694 DbgBreakMsg("illegal value for dcbx_update_lpme_task_state"); 695 break; 696 } 697 } 698 } 699 } 700 701 /******************************************************************************* 702 * Description: Calculate the number of priority PG. 703 * The number of priority pg should be derived from the available traffic type 704 * and pg_pri_orginal_spread configured priorities 705 * 706 * Return: 707 ******************************************************************************/ 708 STATIC void 709 lm_dcbx_cee_get_num_of_pg_traf_type( 710 IN lm_device_t *pdev, 711 IN u32_t pg_pri_orginal_spread[DCBX_MAX_NUM_PRI_PG_ENTRIES], 712 OUT pg_help_data_t *pg_help_data) 713 { 714 u8_t i = 0; 715 u8_t b_pg_found = FALSE; 716 u8_t search_traf_type = 0; 717 u8_t add_traf_type = 0; 718 u8_t add_pg = 0; 719 720 ASSERT_STATIC( DCBX_MAX_NUM_PRI_PG_ENTRIES == 8); 721 722 // Set to invalid 723 for (i = 0; i < ARRSIZE(pg_help_data->pg_entry_data); i++) 724 { 725 pg_help_data->pg_entry_data[i].pg = DCBX_ILLEGAL_PG; 726 } 727 728 for (add_traf_type = 0; add_traf_type < ARRSIZE(pg_help_data->pg_entry_data); add_traf_type++) 729 { 730 ASSERT_STATIC(ARRSIZE(pg_help_data->pg_entry_data) == 731 ARRSIZE(pdev->params.dcbx_port_params.app.traffic_type_priority)); 732 733 b_pg_found = FALSE; 734 if (pdev->params.dcbx_port_params.app.traffic_type_priority[add_traf_type] < MAX_PFC_PRIORITIES) 735 { 736 add_pg = (u8_t)pg_pri_orginal_spread[pdev->params.dcbx_port_params.app.traffic_type_priority[add_traf_type]]; 737 for (search_traf_type = 0; search_traf_type < ARRSIZE(pg_help_data->pg_entry_data); search_traf_type++) 738 { 739 if (pg_help_data->pg_entry_data[search_traf_type].pg == add_pg) 740 { 741 if(0 == (pg_help_data->pg_entry_data[search_traf_type].pg_priority & 742 (1 << pdev->params.dcbx_port_params.app.traffic_type_priority[add_traf_type]))) 743 { 744 pg_help_data->pg_entry_data[search_traf_type].num_of_dif_pri++; 745 } 746 pg_help_data->pg_entry_data[search_traf_type].pg_priority |= 747 (1 << pdev->params.dcbx_port_params.app.traffic_type_priority[add_traf_type]); 748 749 b_pg_found = TRUE; 750 break; 751 } 752 } 753 if(FALSE == b_pg_found) 754 { 755 pg_help_data->pg_entry_data[pg_help_data->num_of_pg].pg = add_pg; 756 pg_help_data->pg_entry_data[pg_help_data->num_of_pg].pg_priority = (1 << pdev->params.dcbx_port_params.app.traffic_type_priority[add_traf_type]); 757 pg_help_data->pg_entry_data[pg_help_data->num_of_pg].num_of_dif_pri = 1; 758 pg_help_data->num_of_pg++; 759 } 760 } 761 } 762 DbgBreakIf(pg_help_data->num_of_pg > LLFC_DRIVER_TRAFFIC_TYPE_MAX); 763 } 764 /******************************************************************************* 765 * Description: Still 766 * 767 * Return: 768 ******************************************************************************/ 769 STATIC void 770 lm_dcbx_fill_cos_entry( 771 lm_device_t *pdev, 772 dcbx_cos_params_t *cos_params, 773 const u32_t pri_join_mask, 774 const u32_t bw, 775 const u8_t pauseable, 776 const u8_t strict) 777 { 778 cos_params->s_pri = strict; 779 cos_params->bw_tbl = bw; 780 cos_params->pri_bitmask = pri_join_mask; 781 782 783 // This filed is only for debbuging in CHIP_IS_E2E3A0(pdev) 784 cos_params->pauseable = pauseable; 785 786 if((DCBX_INVALID_COS_BW != bw)|| 787 (DCBX_S_PRI_INVALID != strict)) 788 { 789 DbgBreakIf(0 == pri_join_mask); 790 791 if(CHIP_IS_E2E3A0(pdev)) 792 { 793 if(pauseable) 794 { 795 DbgBreakIf(0 != LM_DCBX_PFC_PRI_GET_NON_PAUSE(pdev,cos_params->pri_bitmask)); 796 } 797 else 798 { 799 DbgBreakIf(0 != LM_DCBX_PFC_PRI_GET_PAUSE(pdev,cos_params->pri_bitmask)); 800 } 801 } 802 } 803 } 804 805 /** 806 * @description 807 * Disable ETS. 808 * @param pdev 809 * 810 * @return STATIC void 811 */ 812 STATIC void 813 lm_dcbx_ets_disable( 814 INOUT lm_device_t *pdev) 815 { 816 pg_params_t *ets = &pdev->params.dcbx_port_params.ets; 817 818 ets->enabled = FALSE; 819 ets->num_of_cos = 1; 820 821 ets->cos_params[0].pri_bitmask = 0xFF; 822 ets->cos_params[0].bw_tbl = DCBX_INVALID_COS_BW; 823 ets->cos_params[0].s_pri = DCBX_S_PRI_COS_HIGHEST; 824 ets->cos_params[0].pauseable = 825 LM_DCBX_IS_PFC_PRI_SOME_PAUSE(pdev,ets->cos_params[0].pri_bitmask); 826 } 827 /** 828 * @description 829 * Clean up old settings of ets and initialize the COS param 830 * struct. 831 * @param pdev 832 * @param ets 833 * 834 * @return STATIC void 835 */ 836 STATIC void 837 lm_dcbx_init_ets_internal_param( 838 lm_device_t *pdev, 839 pg_params_t *ets) 840 { 841 u8_t i = 0; 842 ets->enabled = FALSE; 843 ets->num_of_cos = 0 ; 844 845 for(i=0; i < ARRSIZE(ets->cos_params) ; i++) 846 { 847 lm_dcbx_fill_cos_entry(pdev, 848 &ets->cos_params[i], 849 0, 850 DCBX_INVALID_COS_BW, 851 FALSE, 852 DCBX_S_PRI_INVALID); 853 } 854 } 855 /******************************************************************************* 856 * Description: single priority group 857 * 858 * Return: 859 ******************************************************************************/ 860 STATIC void 861 lm_dcbx_ets_disabled_entry_data( 862 IN lm_device_t *pdev, 863 OUT cos_help_data_t *cos_data, 864 IN const u32_t pri_join_mask) 865 { 866 // Only one priority than only one COS 867 cos_data->entry_data[0].b_pausable = LM_DCBX_IS_PFC_PRI_ONLY_PAUSE(pdev,pri_join_mask); 868 cos_data->entry_data[0].pri_join_mask = pri_join_mask; 869 cos_data->entry_data[0].cos_bw = 100; 870 cos_data->num_of_cos = 1; 871 } 872 873 /******************************************************************************* 874 * Description: Updating the cos bw. 875 * 876 * Return: 877 ******************************************************************************/ 878 STATIC void 879 lm_dcbx_add_to_cos_bw( 880 IN lm_device_t *pdev, 881 OUT cos_entry_help_data_t *entry_data, 882 IN u8_t pg_bw) 883 { 884 885 if(DCBX_INVALID_COS_BW == entry_data->cos_bw ) 886 { 887 888 entry_data->cos_bw = pg_bw; 889 } 890 else 891 { 892 entry_data->cos_bw += pg_bw; 893 } 894 DbgBreakIf(entry_data->cos_bw > DCBX_MAX_COS_BW); 895 } 896 /******************************************************************************* 897 * Description: single priority group 898 * 899 * Return: 900 ******************************************************************************/ 901 STATIC void 902 lm_dcbx_separate_pauseable_from_non( 903 IN lm_device_t *pdev, 904 OUT cos_help_data_t *cos_data, 905 IN const u32_t *pg_pri_orginal_spread, 906 IN const dcbx_ets_feature_t *ets 907 ) 908 { 909 u32_t pri_tested = 0; 910 u8_t i = 0; 911 u8_t entry = 0; 912 u8_t pg_entry = 0; 913 const u8_t num_of_pri = ARRSIZE(pdev->params.dcbx_port_params.app.traffic_type_priority); 914 915 cos_data->entry_data[0].b_pausable = TRUE; 916 cos_data->entry_data[1].b_pausable = FALSE; 917 cos_data->entry_data[0].pri_join_mask = cos_data->entry_data[1].pri_join_mask = 0; 918 919 for(i=0 ; i < num_of_pri ; i++) 920 { 921 DbgBreakIf(pdev->params.dcbx_port_params.app.traffic_type_priority[i] >= MAX_PFC_PRIORITIES); 922 pri_tested = 1 << pdev->params.dcbx_port_params.app.traffic_type_priority[i]; 923 924 if(pri_tested & LM_DCBX_PFC_PRI_NON_PAUSE_MASK(pdev)) 925 { 926 cos_data->entry_data[1].pri_join_mask |= pri_tested; 927 entry = 1; 928 } 929 else 930 { 931 cos_data->entry_data[0].pri_join_mask |= pri_tested; 932 entry = 0; 933 934 } 935 pg_entry = (u8_t)pg_pri_orginal_spread[pdev->params.dcbx_port_params.app.traffic_type_priority[i]]; 936 // There can be only one strict pg 937 if( pg_entry < DCBX_MAX_NUM_PRI_PG_ENTRIES) 938 { 939 lm_dcbx_add_to_cos_bw(pdev, 940 &(cos_data->entry_data[entry]), 941 DCBX_PG_BW_GET(ets->pg_bw_tbl, pg_entry)); 942 } 943 else 944 { 945 // If we join a group and one is strict than the bw rulls 946 cos_data->entry_data[entry].s_pri = DCBX_S_PRI_COS_HIGHEST; 947 } 948 }//end of for 949 // Both groups must have priorities 950 DbgBreakIf(( 0 == cos_data->entry_data[0].pri_join_mask) && ( 0 == cos_data->entry_data[1].pri_join_mask)); 951 } 952 953 /** 954 * @description 955 * if the number of requested PG-s in CEE is greater than 956 * expected then the results are not determined since this is a 957 * violation of the standard. 958 * @param pdev 959 * @param pg_help_data 960 * @param required_num_of_pg 961 * 962 * @return STATIC lm_status_t 963 * If we weren't successful in reducing the number of PGs to 964 * required_num_of_pg. 965 */ 966 STATIC lm_status_t 967 lm_dcbx_join_pgs( 968 IN lm_device_t *pdev, 969 IN dcbx_ets_feature_t *ets, 970 INOUT pg_help_data_t *pg_help_data, 971 IN const u8_t required_num_of_pg) 972 { 973 lm_status_t lm_status = LM_STATUS_SUCCESS; 974 u8_t entry_joined = pg_help_data->num_of_pg -1; 975 u8_t entry_removed = entry_joined + 1; 976 u8_t pg_joined = 0; 977 978 // Algorithm below limitation (-2) 979 if((required_num_of_pg < 2 )|| 980 (ARRSIZE(pg_help_data->pg_entry_data) <= pg_help_data->num_of_pg)|| 981 ( pg_help_data->num_of_pg <= required_num_of_pg)) 982 { 983 DbgBreakMsg("lm_dcbx_join_pg_data required_num_of_pg can't be zero"); 984 return LM_STATUS_FAILURE; 985 } 986 987 while(required_num_of_pg < pg_help_data->num_of_pg) 988 { 989 entry_joined = pg_help_data->num_of_pg -2; 990 entry_removed = entry_joined + 1; 991 992 pg_help_data->pg_entry_data[entry_joined].pg_priority |= 993 pg_help_data->pg_entry_data[entry_removed].pg_priority; 994 995 pg_help_data->pg_entry_data[entry_joined].num_of_dif_pri += 996 pg_help_data->pg_entry_data[entry_removed].num_of_dif_pri; 997 998 if((DCBX_STRICT_PRI_PG == pg_help_data->pg_entry_data[entry_joined].pg ) || 999 (DCBX_STRICT_PRI_PG == pg_help_data->pg_entry_data[entry_removed].pg)) 1000 { 1001 // Entries joined strict priority rules 1002 pg_help_data->pg_entry_data[entry_joined].pg = DCBX_STRICT_PRI_PG; 1003 } 1004 else 1005 { 1006 // Entries can be joined join BW 1007 pg_joined = DCBX_PG_BW_GET(ets->pg_bw_tbl, pg_help_data->pg_entry_data[entry_joined].pg) + 1008 DCBX_PG_BW_GET(ets->pg_bw_tbl, pg_help_data->pg_entry_data[entry_removed].pg); 1009 1010 DCBX_PG_BW_SET(ets->pg_bw_tbl, pg_help_data->pg_entry_data[entry_joined].pg,pg_joined); 1011 } 1012 // Joined the entries 1013 pg_help_data->num_of_pg--; 1014 } 1015 return lm_status; 1016 } 1017 /** 1018 * @description 1019 * Fill pause entries in entry_data 1020 * @param pdev 1021 * @param entry_data 1022 * 1023 * @return STATIC void 1024 */ 1025 STATIC void 1026 lm_dcbx_ets_fill_cos_entry_data_as_pause( 1027 IN lm_device_t *pdev, 1028 OUT cos_entry_help_data_t *entry_data, 1029 IN const u32_t pri_join_mask 1030 ) 1031 { 1032 entry_data->b_pausable = TRUE; 1033 entry_data->pri_join_mask = LM_DCBX_PFC_PRI_GET_PAUSE(pdev,pri_join_mask); 1034 } 1035 1036 /** 1037 * @description 1038 * Fill pause entries in entry_data 1039 * @param pdev 1040 * @param entry_data 1041 * 1042 * @return STATIC void 1043 */ 1044 STATIC void 1045 lm_dcbx_ets_fill_cos_entry_data_as_non_pause( 1046 IN lm_device_t *pdev, 1047 OUT cos_entry_help_data_t *entry_data, 1048 IN const u32_t pri_join_mask 1049 ) 1050 { 1051 entry_data->b_pausable = FALSE; 1052 entry_data->pri_join_mask = LM_DCBX_PFC_PRI_GET_NON_PAUSE(pdev,pri_join_mask); 1053 } 1054 /******************************************************************************* 1055 * Description: single priority group 1056 * 1057 * Return: 1058 ******************************************************************************/ 1059 STATIC void 1060 lm_dcbx_2cos_limit_cee_single_pg_to_cos_params( 1061 IN lm_device_t *pdev, 1062 IN pg_help_data_t *pg_help_data, 1063 OUT cos_help_data_t *cos_data, 1064 IN const u32_t pri_join_mask, 1065 IN const u8_t num_of_dif_pri 1066 ) 1067 { 1068 u8_t i = 0; 1069 u32_t pri_tested = 0; 1070 u32_t pri_mask_without_pri = 0; 1071 1072 if(1 == num_of_dif_pri) 1073 { 1074 // Only one priority than only one COS 1075 lm_dcbx_ets_disabled_entry_data(pdev,cos_data,pri_join_mask); 1076 return; 1077 } 1078 1079 if( pg_help_data->pg_entry_data[0].pg < DCBX_MAX_NUM_PG_BW_ENTRIES) 1080 {// BW limited 1081 // If there are both pauseable and non-pauseable priorities, the pauseable priorities go to the first queue and the non-pauseable 1082 // priorities go to the second queue. 1083 if(LM_DCBX_IS_PFC_PRI_MIX_PAUSE(pdev,pri_join_mask)) 1084 { 1085 DbgBreakIf( 1 == num_of_dif_pri ); 1086 // Pause able 1087 lm_dcbx_ets_fill_cos_entry_data_as_pause( 1088 pdev, 1089 &cos_data->entry_data[0], 1090 pri_join_mask); 1091 // Non pause able. 1092 lm_dcbx_ets_fill_cos_entry_data_as_non_pause( 1093 pdev, 1094 &cos_data->entry_data[1], 1095 pri_join_mask); 1096 1097 if(2 == num_of_dif_pri) 1098 { 1099 cos_data->entry_data[0].cos_bw = 50; 1100 cos_data->entry_data[1].cos_bw = 50; 1101 } 1102 if (3 == num_of_dif_pri) 1103 { 1104 // We need to find out how has only one priority and how has two priorities. 1105 // If the pri_bitmask is a power of 2 than there is only one priority. 1106 if(POWER_OF_2(LM_DCBX_PFC_PRI_GET_PAUSE(pdev,pri_join_mask))) 1107 { 1108 DbgBreakIf(POWER_OF_2(LM_DCBX_PFC_PRI_GET_NON_PAUSE(pdev,pri_join_mask))); 1109 cos_data->entry_data[0].cos_bw = 33; 1110 cos_data->entry_data[1].cos_bw = 67; 1111 } 1112 else 1113 { 1114 DbgBreakIf(FALSE == POWER_OF_2(LM_DCBX_PFC_PRI_GET_NON_PAUSE(pdev,pri_join_mask))); 1115 cos_data->entry_data[0].cos_bw = 67; 1116 cos_data->entry_data[1].cos_bw = 33; 1117 } 1118 } 1119 } 1120 else if(LM_DCBX_IS_PFC_PRI_ONLY_PAUSE(pdev,pri_join_mask)) 1121 {// If there are only pauseable priorities, then one/two priorities go 1122 // to the first queue and one priority goes to the second queue. 1123 if(2 == num_of_dif_pri) 1124 { 1125 cos_data->entry_data[0].cos_bw = 50; 1126 cos_data->entry_data[1].cos_bw = 50; 1127 } 1128 else 1129 { 1130 DbgBreakIf(3 != num_of_dif_pri); 1131 cos_data->entry_data[0].cos_bw = 67; 1132 cos_data->entry_data[1].cos_bw = 33; 1133 } 1134 cos_data->entry_data[0].b_pausable = cos_data->entry_data[1].b_pausable = TRUE; 1135 // All priorities except FCOE 1136 cos_data->entry_data[0].pri_join_mask = (pri_join_mask & ((u8_t)~(1 << pdev->params.dcbx_port_params.app.traffic_type_priority[LLFC_TRAFFIC_TYPE_FCOE]))); 1137 // Only FCOE priority. 1138 cos_data->entry_data[1].pri_join_mask = (1 << pdev->params.dcbx_port_params.app.traffic_type_priority[LLFC_TRAFFIC_TYPE_FCOE]); 1139 } 1140 else 1141 {//If there are only non-pauseable priorities, they will all go to the same queue. 1142 DbgBreakIf(FALSE == LM_DCBX_IS_PFC_PRI_ONLY_NON_PAUSE(pdev,pri_join_mask)); 1143 lm_dcbx_ets_disabled_entry_data(pdev,cos_data,pri_join_mask); 1144 } 1145 } 1146 else 1147 { 1148 // priority group which is not BW limited (PG#15): 1149 DbgBreakIf(DCBX_STRICT_PRI_PG != pg_help_data->pg_entry_data[0].pg); 1150 if(LM_DCBX_IS_PFC_PRI_MIX_PAUSE(pdev,pri_join_mask)) 1151 { 1152 // If there are both pauseable and non-pauseable priorities, the pauseable priorities go 1153 // to the first queue and the non-pauseable priorities go to the second queue. 1154 if(LM_DCBX_PFC_PRI_GET_PAUSE(pdev,pri_join_mask) > LM_DCBX_PFC_PRI_GET_NON_PAUSE(pdev,pri_join_mask)) 1155 { 1156 cos_data->entry_data[0].s_pri = DCBX_S_PRI_COS_HIGHEST; 1157 cos_data->entry_data[1].s_pri = DCBX_S_PRI_COS_NEXT_LOWER_PRI(DCBX_S_PRI_COS_HIGHEST); 1158 } 1159 else 1160 { 1161 cos_data->entry_data[1].s_pri = DCBX_S_PRI_COS_HIGHEST; 1162 cos_data->entry_data[0].s_pri = DCBX_S_PRI_COS_NEXT_LOWER_PRI(DCBX_S_PRI_COS_HIGHEST); 1163 } 1164 // Pause able 1165 lm_dcbx_ets_fill_cos_entry_data_as_pause( 1166 pdev, 1167 &cos_data->entry_data[0], 1168 pri_join_mask); 1169 // Non pause-able. 1170 lm_dcbx_ets_fill_cos_entry_data_as_non_pause( 1171 pdev, 1172 &cos_data->entry_data[1], 1173 pri_join_mask); 1174 } 1175 else 1176 { 1177 // If there are only pauseable priorities or only non-pauseable, the lower priorities 1178 // go to the first queue and the higher priorities go to the second queue. 1179 cos_data->entry_data[0].b_pausable = cos_data->entry_data[1].b_pausable = LM_DCBX_IS_PFC_PRI_ONLY_PAUSE(pdev,pri_join_mask); 1180 1181 for(i=0 ; i < ARRSIZE(pdev->params.dcbx_port_params.app.traffic_type_priority) ; i++) 1182 { 1183 DbgBreakIf(pdev->params.dcbx_port_params.app.traffic_type_priority[i] >= MAX_PFC_PRIORITIES); 1184 pri_tested = 1 << pdev->params.dcbx_port_params.app.traffic_type_priority[i]; 1185 // Remove priority tested 1186 pri_mask_without_pri = (pri_join_mask & ((u8_t)(~pri_tested))); 1187 if( pri_mask_without_pri < pri_tested ) 1188 { 1189 break; 1190 } 1191 } 1192 1193 if(i == ARRSIZE(pdev->params.dcbx_port_params.app.traffic_type_priority)) 1194 { 1195 DbgBreakMsg("lm_dcbx_fill_cos_params : Invalid value for pri_join_mask could not find a priority \n"); 1196 } 1197 cos_data->entry_data[0].pri_join_mask = pri_mask_without_pri; 1198 cos_data->entry_data[1].pri_join_mask = pri_tested; 1199 // Both queues are strict priority, and that with the highest priority 1200 // gets the highest strict priority in the arbiter. 1201 cos_data->entry_data[1].s_pri = DCBX_S_PRI_COS_HIGHEST; 1202 cos_data->entry_data[0].s_pri = DCBX_S_PRI_COS_NEXT_LOWER_PRI(DCBX_S_PRI_COS_HIGHEST); 1203 } 1204 } 1205 1206 } 1207 /******************************************************************************* 1208 * Description: Still 1209 * 1210 * Return: 1211 ******************************************************************************/ 1212 STATIC void 1213 lm_dcbx_2cos_limit_cee_two_pg_to_cos_params( 1214 IN lm_device_t *pdev, 1215 IN pg_help_data_t *pg_help_data, 1216 IN const dcbx_ets_feature_t *ets, 1217 OUT cos_help_data_t *cos_data, 1218 IN const u32_t *pg_pri_orginal_spread, 1219 IN u32_t pri_join_mask, 1220 IN u8_t num_of_dif_pri) 1221 { 1222 u8_t i = 0; 1223 u8_t pg[DCBX_COS_MAX_NUM_E2E3A0] = {0}; 1224 1225 // If there are both pauseable and non-pauseable priorities, the pauseable priorities 1226 // go to the first queue and the non-pauseable priorities go to the second queue. 1227 if(LM_DCBX_IS_PFC_PRI_MIX_PAUSE(pdev,pri_join_mask)) 1228 { 1229 if(LM_DCBX_IS_PFC_PRI_MIX_PAUSE(pdev, pg_help_data->pg_entry_data[0].pg_priority) || 1230 LM_DCBX_IS_PFC_PRI_MIX_PAUSE(pdev, pg_help_data->pg_entry_data[1].pg_priority)) 1231 { 1232 // If one PG contains both pauseable and non-pauseable priorities then ETS is disabled. 1233 DbgMessage(pdev, WARN, "lm_dcbx_fill_cos_params : PG contains both pauseable and non-pauseable " 1234 "priorities -> ETS is disabled. \n"); 1235 lm_dcbx_separate_pauseable_from_non(pdev,cos_data,pg_pri_orginal_spread,ets); 1236 // ETS disabled wrong configuration 1237 pdev->params.dcbx_port_params.ets.enabled = FALSE; 1238 return; 1239 } 1240 1241 // Pause-able 1242 cos_data->entry_data[0].b_pausable = TRUE; 1243 // Non pause-able. 1244 cos_data->entry_data[1].b_pausable = FALSE; 1245 if(LM_DCBX_IS_PFC_PRI_ONLY_PAUSE(pdev, pg_help_data->pg_entry_data[0].pg_priority)) 1246 {// 0 is pause-able 1247 cos_data->entry_data[0].pri_join_mask = pg_help_data->pg_entry_data[0].pg_priority; 1248 pg[0] = pg_help_data->pg_entry_data[0].pg; 1249 cos_data->entry_data[1].pri_join_mask = pg_help_data->pg_entry_data[1].pg_priority; 1250 pg[1] = pg_help_data->pg_entry_data[1].pg; 1251 } 1252 else 1253 {// 1 is pause-able 1254 cos_data->entry_data[0].pri_join_mask = pg_help_data->pg_entry_data[1].pg_priority; 1255 pg[0] = pg_help_data->pg_entry_data[1].pg; 1256 cos_data->entry_data[1].pri_join_mask = pg_help_data->pg_entry_data[0].pg_priority; 1257 pg[1] = pg_help_data->pg_entry_data[0].pg; 1258 } 1259 } 1260 else 1261 { 1262 //If there are only pauseable priorities or only non-pauseable, each PG goes to a queue. 1263 cos_data->entry_data[0].b_pausable = cos_data->entry_data[1].b_pausable = LM_DCBX_IS_PFC_PRI_ONLY_PAUSE(pdev,pri_join_mask); 1264 cos_data->entry_data[0].pri_join_mask = pg_help_data->pg_entry_data[0].pg_priority; 1265 pg[0] = pg_help_data->pg_entry_data[0].pg; 1266 cos_data->entry_data[1].pri_join_mask = pg_help_data->pg_entry_data[1].pg_priority; 1267 pg[1] = pg_help_data->pg_entry_data[1].pg; 1268 } 1269 1270 // There can be only one strict pg 1271 for(i=0 ; i < ARRSIZE(pg) ; i++) 1272 { 1273 if( pg[i] < DCBX_MAX_NUM_PG_BW_ENTRIES) 1274 { 1275 cos_data->entry_data[i].cos_bw = DCBX_PG_BW_GET( ets->pg_bw_tbl,pg[i]); 1276 } 1277 else 1278 { 1279 cos_data->entry_data[i].s_pri = DCBX_S_PRI_COS_HIGHEST; 1280 } 1281 } 1282 } 1283 1284 /******************************************************************************* 1285 * Description: Still 1286 * 1287 * Return: 1288 ******************************************************************************/ 1289 STATIC void 1290 lm_dcbx_2cos_limit_cee_three_pg_to_cos_params( 1291 IN lm_device_t *pdev, 1292 IN pg_help_data_t *pg_help_data, 1293 IN const dcbx_ets_feature_t *ets, 1294 OUT cos_help_data_t *cos_data, 1295 IN const u32_t *pg_pri_orginal_spread, 1296 IN u32_t pri_join_mask, 1297 IN u8_t num_of_dif_pri) 1298 { 1299 u8_t i = 0; 1300 u32_t pri_tested = 0; 1301 u8_t entry = 0; 1302 u8_t pg_entry = 0; 1303 u8_t b_found_strict = FALSE; 1304 u8_t num_of_pri = ARRSIZE(pdev->params.dcbx_port_params.app.traffic_type_priority); 1305 DbgBreakIf(3 != num_of_pri); 1306 cos_data->entry_data[0].pri_join_mask = cos_data->entry_data[1].pri_join_mask = 0; 1307 //- If there are both pauseable and non-pauseable priorities, the pauseable priorities go to the first 1308 // queue and the non-pauseable priorities go to the second queue. 1309 if(LM_DCBX_IS_PFC_PRI_MIX_PAUSE(pdev,pri_join_mask)) 1310 { 1311 lm_dcbx_separate_pauseable_from_non(pdev,cos_data,pg_pri_orginal_spread,ets); 1312 } 1313 else 1314 { 1315 DbgBreakIf(!(LM_DCBX_IS_PFC_PRI_ONLY_NON_PAUSE(pdev,pri_join_mask) || 1316 LM_DCBX_IS_PFC_PRI_ONLY_PAUSE(pdev,pri_join_mask))); 1317 1318 //- If two BW-limited PG-s were combined to one queue, the BW is their sum. 1319 //- If there are only pauseable priorities or only non-pauseable, and there are both BW-limited and 1320 // non-BW-limited PG-s, the BW-limited PG/s go to one queue and the non-BW-limited PG/s go to the 1321 // second queue. 1322 //- If there are only pauseable priorities or only non-pauseable and all are BW limited, then 1323 // two priorities go to the first queue and one priority goes to the second queue. 1324 1325 // We will join this two cases: 1326 // if one is BW limited he will go to the secoend queue otherwise the last priority will get it 1327 1328 cos_data->entry_data[0].b_pausable = cos_data->entry_data[1].b_pausable = LM_DCBX_IS_PFC_PRI_ONLY_PAUSE(pdev,pri_join_mask); 1329 1330 for(i=0 ; i < num_of_pri; i++) 1331 { 1332 DbgBreakIf(pdev->params.dcbx_port_params.app.traffic_type_priority[i] >= MAX_PFC_PRIORITIES); 1333 pri_tested = 1 << pdev->params.dcbx_port_params.app.traffic_type_priority[i]; 1334 pg_entry = (u8_t)pg_pri_orginal_spread[pdev->params.dcbx_port_params.app.traffic_type_priority[i]]; 1335 1336 if(pg_entry < DCBX_MAX_NUM_PG_BW_ENTRIES) 1337 { 1338 entry = 0; 1339 1340 if((i == (num_of_pri-1))&& 1341 (FALSE == b_found_strict) ) 1342 {/* last entry will be handled separately */ 1343 // If no priority is strict than last enty goes to last queue. 1344 entry = 1; 1345 } 1346 cos_data->entry_data[entry].pri_join_mask |= pri_tested; 1347 lm_dcbx_add_to_cos_bw(pdev, &(cos_data->entry_data[entry]), DCBX_PG_BW_GET(ets->pg_bw_tbl, pg_entry)); 1348 } 1349 else 1350 { 1351 DbgBreakIf(TRUE == b_found_strict ); 1352 b_found_strict = TRUE; 1353 cos_data->entry_data[1].pri_join_mask |= pri_tested; 1354 // If we join a group and one is strict than the bw rulls 1355 cos_data->entry_data[1].s_pri = DCBX_S_PRI_COS_HIGHEST; 1356 } 1357 1358 }//end of for 1359 } 1360 } 1361 /** 1362 * @description 1363 * Also for e3 and e2. 1364 * @param pdev 1365 * @param pg_help_data 1366 * @param ets 1367 * @param cos_data 1368 * @param pg_pri_orginal_spread 1369 * @param pri_join_mask 1370 * @param num_of_dif_pri 1371 * 1372 * @return STATIC void 1373 */ 1374 STATIC void 1375 lm_dcbx_2cos_limit_cee_fill_cos_params( 1376 IN lm_device_t *pdev, 1377 IN pg_help_data_t *pg_help_data, 1378 IN dcbx_ets_feature_t *ets, 1379 OUT cos_help_data_t *cos_data, 1380 IN const u32_t *pg_pri_orginal_spread, 1381 IN u32_t pri_join_mask, 1382 IN u8_t num_of_dif_pri) 1383 { 1384 DbgBreakIf(FALSE == CHIP_IS_E2E3A0(pdev)); 1385 1386 // Default settings 1387 cos_data->num_of_cos = DCBX_COS_MAX_NUM_E2E3A0; 1388 1389 switch(pg_help_data->num_of_pg) 1390 { 1391 case 1: 1392 //single priority group 1393 lm_dcbx_2cos_limit_cee_single_pg_to_cos_params( 1394 pdev, 1395 pg_help_data, 1396 cos_data, 1397 pri_join_mask, 1398 num_of_dif_pri); 1399 break; 1400 case 2: 1401 lm_dcbx_2cos_limit_cee_two_pg_to_cos_params( 1402 pdev, 1403 pg_help_data, 1404 ets, 1405 cos_data, 1406 pg_pri_orginal_spread, 1407 pri_join_mask, 1408 num_of_dif_pri); 1409 break; 1410 1411 case 3: 1412 // Three pg must mean three priorities. 1413 lm_dcbx_2cos_limit_cee_three_pg_to_cos_params( 1414 pdev, 1415 pg_help_data, 1416 ets, 1417 cos_data, 1418 pg_pri_orginal_spread, 1419 pri_join_mask, 1420 num_of_dif_pri); 1421 1422 break; 1423 default: 1424 DbgBreakMsg("lm_dcbx_fill_cos_params :Wrong pg_help_data->num_of_pg \n"); 1425 lm_dcbx_ets_disabled_entry_data(pdev,cos_data,pri_join_mask); 1426 } 1427 } 1428 /** 1429 * @description 1430 * Fill cos params in E3B0 A VOQ is PFC enabled if there is one 1431 * or more priorities mapped to it which is PFC enabled. 1432 * @param pdev 1433 * @param entry_data 1434 * @param pri_join_mask 1435 * @param bw 1436 * @param sp 1437 * 1438 * @return STATIC void 1439 */ 1440 STATIC void 1441 lm_dcbx_fill_cos( 1442 IN lm_device_t *pdev, 1443 OUT cos_entry_help_data_t *entry_data, 1444 IN const u32_t pri_join_mask, 1445 IN const u32_t bw, 1446 IN const u8_t s_pri) 1447 { 1448 1449 DbgBreakIf(FALSE == CHIP_IS_E3B0(pdev)); 1450 1451 entry_data->cos_bw = bw; 1452 entry_data->s_pri = s_pri; 1453 //Set the entry it wasn't set before 1454 entry_data->pri_join_mask = pri_join_mask; 1455 1456 // A VOQ is PFC enabled if there is one or more priorities 1457 // mapped to it which is PFC enabled. 1458 entry_data->b_pausable = 1459 LM_DCBX_IS_PFC_PRI_SOME_PAUSE(pdev, entry_data->pri_join_mask); 1460 1461 } 1462 1463 /** 1464 * @description 1465 * Spread the strict priority according to 1466 * num_spread_of_entries. 1467 * 1468 * 2.Arbitration between the VOQ-s will be the same as the 1469 * arbitration requirements between the PG-s except that if 1470 * multiple VOQ-s are used for priorities in PG15 then there 1471 * will be strict priority ordering between them according to 1472 * the order of priorities. 1473 * @param pdev 1474 * @param cos_data 1475 * @param inout_entry 1476 * @param strict_need_num_of_entries 1477 * @param strict_app_pris 1478 * 1479 * @return STATIC lm_status_t 1480 */ 1481 STATIC lm_status_t 1482 lm_dcbx_spread_strict_pri( 1483 IN lm_device_t *pdev, 1484 OUT cos_help_data_t *cos_data, 1485 IN u8_t entry, 1486 IN u8_t num_spread_of_entries, 1487 IN u8_t strict_app_pris) 1488 { 1489 u8_t stict_pri = DCBX_S_PRI_COS_HIGHEST; 1490 u8_t num_of_app_pri = MAX_PFC_PRIORITIES; 1491 u8_t app_pri_bit = 0; 1492 lm_status_t lm_status = LM_STATUS_SUCCESS; 1493 1494 DbgBreakIf(FALSE == CHIP_IS_E3B0(pdev)); 1495 1496 while((num_spread_of_entries)&& 1497 (0 < num_of_app_pri)) 1498 { 1499 app_pri_bit = 1 << (num_of_app_pri -1 ); 1500 if(app_pri_bit & strict_app_pris) 1501 { 1502 num_spread_of_entries--; 1503 if(0 == num_spread_of_entries) 1504 { 1505 // last entry needed put all the entries left 1506 lm_dcbx_fill_cos(pdev, 1507 &(cos_data->entry_data[entry]), 1508 strict_app_pris, 1509 DCBX_INVALID_COS_BW, 1510 stict_pri); 1511 } 1512 else 1513 { 1514 strict_app_pris &= ~app_pri_bit; 1515 lm_dcbx_fill_cos(pdev, 1516 &(cos_data->entry_data[entry]), 1517 app_pri_bit, 1518 DCBX_INVALID_COS_BW, 1519 stict_pri); 1520 } 1521 1522 stict_pri = DCBX_S_PRI_COS_NEXT_LOWER_PRI(stict_pri); 1523 entry++; 1524 } 1525 num_of_app_pri--; 1526 } 1527 1528 if(0 != num_spread_of_entries) 1529 { 1530 DbgBreakMsg("lm_dcbx_spread_strict_pri- This is a bug "); 1531 lm_status = LM_STATUS_FAILURE; 1532 } 1533 1534 return lm_status; 1535 } 1536 /** 1537 * @description 1538 * Try to split the strict priority to num_spread_of_entries. 1539 * If not possible all of the priorities will be in one entry. 1540 * @param pdev 1541 * @param cos_data 1542 * @param entry 1543 * @param num_spread_of_entries 1544 * @param strict_app_pris 1545 * 1546 * @return STATIC u8_t 1547 * Num of entries cos_data used. 1548 */ 1549 STATIC u8_t 1550 lm_dcbx_cee_fill_strict_pri( 1551 IN lm_device_t *pdev, 1552 OUT cos_help_data_t *cos_data, 1553 INOUT u8_t entry, 1554 IN u8_t num_spread_of_entries, 1555 IN u8_t strict_app_pris) 1556 { 1557 1558 lm_status_t lm_status = LM_STATUS_SUCCESS; 1559 1560 DbgBreakIf(FALSE == CHIP_IS_E3B0(pdev)); 1561 1562 lm_status = lm_dcbx_spread_strict_pri(pdev, 1563 cos_data, 1564 entry, 1565 num_spread_of_entries, 1566 strict_app_pris); 1567 if(LM_STATUS_SUCCESS != lm_status) 1568 { 1569 lm_dcbx_fill_cos(pdev, 1570 &(cos_data->entry_data[entry]), 1571 strict_app_pris, 1572 DCBX_INVALID_COS_BW, 1573 DCBX_S_PRI_COS_HIGHEST); 1574 return 1; 1575 1576 } 1577 1578 return num_spread_of_entries; 1579 } 1580 /** 1581 * @description 1582 * In E3 the allocation is based only on the PG configuration. 1583 * PFC will not have an effect on the mapping. The mapping is 1584 * done according to the following priorities: 1585 * 1. Allocate a single VOQ to PG15 if there is at least one 1586 * priority mapped to PG15. 1587 * 2. Allocate the rest of the VOQ-s to the other PG-s. 1588 * 3. If there are still VOQ-s which have no associated PG, then 1589 * associate these VOQ-s to PG15. These PG-s will be used for SP 1590 * between priorities on PG15. 1591 * 1592 * @param pdev 1593 * @param pg_help_data 1594 * @param ets 1595 * @param cos_data 1596 * @param pg_pri_orginal_spread 1597 * @param pri_join_mask 1598 * @param num_of_dif_pri 1599 * 1600 * @return STATIC void 1601 */ 1602 STATIC void 1603 lm_dcbx_cee_fill_cos_params( 1604 IN lm_device_t *pdev, 1605 IN pg_help_data_t *pg_help_data, 1606 IN dcbx_ets_feature_t *ets, 1607 OUT cos_help_data_t *cos_data, 1608 IN const u32_t pri_join_mask) 1609 { 1610 lm_status_t lm_status = LM_STATUS_SUCCESS; 1611 u8_t need_num_of_entries = 0; 1612 u8_t i = 0; 1613 u8_t entry = 0; 1614 1615 DbgBreakIf(FALSE == CHIP_IS_E3B0(pdev)); 1616 1617 // if the number of requested PG-s in CEE is greater than 3 1618 // then the results are not determined since this is a violation 1619 // of the standard. 1620 if(DCBX_COS_MAX_NUM_E3B0 < pg_help_data->num_of_pg) 1621 { 1622 DbgBreakMsg("lm_dcbx_cee_e3b0_fill_cos_params :Wrong pg_help_data->num_of_pg \n"); 1623 lm_status = lm_dcbx_join_pgs(pdev, 1624 ets, 1625 pg_help_data, 1626 DCBX_COS_MAX_NUM_E3B0); 1627 1628 if(LM_STATUS_SUCCESS != lm_status) 1629 { 1630 // If we weren't successful in reducing the number of PGs we will disables ETS. 1631 lm_dcbx_ets_disabled_entry_data(pdev,cos_data,pri_join_mask); 1632 return; 1633 } 1634 } 1635 1636 for(i = 0 ; i < pg_help_data->num_of_pg; i++) 1637 { 1638 1639 if(pg_help_data->pg_entry_data[i].pg < DCBX_MAX_NUM_PG_BW_ENTRIES) 1640 { 1641 // Fill BW entry. 1642 lm_dcbx_fill_cos(pdev, 1643 &(cos_data->entry_data[entry]), 1644 pg_help_data->pg_entry_data[i].pg_priority, 1645 DCBX_PG_BW_GET(ets->pg_bw_tbl, pg_help_data->pg_entry_data[i].pg), 1646 DCBX_S_PRI_INVALID); 1647 entry++; 1648 } 1649 else 1650 { 1651 DbgBreakIf(DCBX_STRICT_PRI_PG != pg_help_data->pg_entry_data[i].pg ); 1652 1653 need_num_of_entries = min((u8_t)pg_help_data->pg_entry_data[i].num_of_dif_pri, 1654 (u8_t)(((u8_t)DCBX_COS_MAX_NUM_E3B0 - pg_help_data->num_of_pg) + 1/*current entry*/)); 1655 1656 // 3. If there are still VOQ-s which have no associated PG, then 1657 // associate these VOQ-s to PG15. These PG-s will be used for SP 1658 // between priorities on PG15. 1659 entry += lm_dcbx_cee_fill_strict_pri(pdev, 1660 cos_data, 1661 entry, 1662 need_num_of_entries, 1663 (u8_t)pg_help_data->pg_entry_data[i].pg_priority); 1664 1665 } 1666 1667 }//end of for 1668 1669 // the entry will represent the number of COS used 1670 cos_data->num_of_cos = entry; 1671 1672 DbgBreakIf(DCBX_COS_MAX_NUM_E3B0 < cos_data->num_of_cos ); 1673 } 1674 /** 1675 * @description 1676 * Get the COS parameters according to ETS and PFC receive 1677 * configuration 1678 * @param pdev 1679 * @param pg_help_data 1680 * @param ets 1681 * @param pg_pri_orginal_spread 1682 * 1683 * @return STATIC void 1684 */ 1685 STATIC void 1686 lm_dcbx_fill_cos_params( 1687 IN lm_device_t *pdev, 1688 IN pg_help_data_t *pg_help_data, 1689 IN dcbx_ets_feature_t *ets, 1690 IN const u32_t *pg_pri_orginal_spread) 1691 { 1692 cos_help_data_t cos_data = {{{0}}}; 1693 u8_t i = 0; 1694 u8_t j = 0; 1695 u32_t pri_join_mask = 0; 1696 u8_t num_of_dif_pri = 0; 1697 1698 // Validate the pg value 1699 for(i=0; i < pg_help_data->num_of_pg ; i++) 1700 { 1701 DbgBreakIf((DCBX_STRICT_PRI_PG != pg_help_data->pg_entry_data[i].pg) && 1702 (DCBX_MAX_NUM_PG_BW_ENTRIES <= pg_help_data->pg_entry_data[i].pg)); 1703 pri_join_mask |= pg_help_data->pg_entry_data[i].pg_priority; 1704 num_of_dif_pri += pg_help_data->pg_entry_data[i].num_of_dif_pri; 1705 } 1706 1707 //default settings 1708 cos_data.num_of_cos = 1; 1709 for(i=0; i < ARRSIZE(cos_data.entry_data) ; i++) 1710 { 1711 cos_data.entry_data[i].pri_join_mask = 0; 1712 cos_data.entry_data[i].b_pausable = FALSE; 1713 cos_data.entry_data[i].s_pri = DCBX_S_PRI_INVALID; 1714 cos_data.entry_data[i].cos_bw = DCBX_INVALID_COS_BW; 1715 } 1716 1717 DbgBreakIf((0 == num_of_dif_pri) && (3 < num_of_dif_pri)); 1718 if(CHIP_IS_E3B0(pdev)) 1719 { 1720 lm_dcbx_cee_fill_cos_params( 1721 pdev, 1722 pg_help_data, 1723 ets, 1724 &cos_data, 1725 pri_join_mask); 1726 } 1727 else 1728 { 1729 DbgBreakIf(FALSE == CHIP_IS_E2E3A0(pdev)); 1730 lm_dcbx_2cos_limit_cee_fill_cos_params( 1731 pdev, 1732 pg_help_data, 1733 ets, 1734 &cos_data, 1735 pg_pri_orginal_spread, 1736 pri_join_mask, 1737 num_of_dif_pri); 1738 } 1739 1740 for(i=0; i < cos_data.num_of_cos ; i++) 1741 { 1742 lm_dcbx_fill_cos_entry(pdev, 1743 &pdev->params.dcbx_port_params.ets.cos_params[i], 1744 cos_data.entry_data[i].pri_join_mask, 1745 cos_data.entry_data[i].cos_bw, 1746 cos_data.entry_data[i].b_pausable, 1747 cos_data.entry_data[i].s_pri); 1748 } 1749 1750 DbgBreakIf(0 == cos_data.num_of_cos); 1751 1752 DbgBreakIf(pri_join_mask != (pdev->params.dcbx_port_params.ets.cos_params[0].pri_bitmask | 1753 pdev->params.dcbx_port_params.ets.cos_params[1].pri_bitmask | 1754 pdev->params.dcbx_port_params.ets.cos_params[2].pri_bitmask)); 1755 1756 // debugging make sure the same priority isn't mapped to to COS 1757 for(i = 0 ; i < cos_data.num_of_cos; i++) 1758 { 1759 for(j = i+1 ; j < cos_data.num_of_cos; j++) 1760 { 1761 DbgBreakIf(0 != (pdev->params.dcbx_port_params.ets.cos_params[i].pri_bitmask & 1762 pdev->params.dcbx_port_params.ets.cos_params[j].pri_bitmask)); 1763 } 1764 } 1765 1766 pdev->params.dcbx_port_params.ets.num_of_cos = cos_data.num_of_cos ; 1767 } 1768 /** 1769 * CQ60417 : If remote feature is not found, we disable the 1770 * feature unless user explicitly configured feature (copycat 1771 * switch behavior) 1772 * @param pdev 1773 * @param error - error flag sent from DCBX. 1774 * @param remote_tlv_feature_flag - Must be one of the 1775 * DCBX_REMOTE_XXX_TLV_NOT_FOUND 1776 * 1777 * @return STATIC u8_t - 1778 */ 1779 STATIC u8_t 1780 lm_dcbx_is_feature_dis_remote_tlv( 1781 INOUT lm_device_t *pdev, 1782 IN const u32_t error, 1783 IN const u32_t remote_tlv_feature_flag 1784 ) 1785 { 1786 u8_t const mfw_config = lm_dcbx_check_drv_flags(pdev, DRV_FLAGS_DCB_MFW_CONFIGURED); 1787 u8_t const ret_feature_dis = (remote_tlv_feature_flag == GET_FLAGS(error ,remote_tlv_feature_flag)) && 1788 (FALSE == mfw_config); 1789 1790 DbgBreakIf(0 == GET_FLAGS(remote_tlv_feature_flag , 1791 (DCBX_REMOTE_ETS_TLV_NOT_FOUND | 1792 DCBX_REMOTE_PFC_TLV_NOT_FOUND | 1793 DCBX_REMOTE_APP_TLV_NOT_FOUND))); 1794 1795 return ret_feature_dis; 1796 } 1797 1798 /******************************************************************************* 1799 * Description: Translate from ETS parameter to COS paramters 1800 * 1801 * Return: 1802 ******************************************************************************/ 1803 STATIC void 1804 lm_dcbx_get_ets_cee_feature( 1805 INOUT lm_device_t *pdev, 1806 INOUT dcbx_ets_feature_t *ets, 1807 IN const u32_t error) 1808 { 1809 u32_t pg_pri_orginal_spread[DCBX_MAX_NUM_PRI_PG_ENTRIES] = {0}; 1810 pg_help_data_t pg_help_data = {{{0}}}; 1811 const u8_t is_ets_dis_remote_tlv = lm_dcbx_is_feature_dis_remote_tlv( 1812 pdev, 1813 error, 1814 DCBX_REMOTE_ETS_TLV_NOT_FOUND); 1815 // Clean up old settings of ets on COS 1816 lm_dcbx_init_ets_internal_param(pdev, 1817 &(pdev->params.dcbx_port_params.ets)); 1818 1819 if(DCBX_MIB_IS_ETS_ENABLED(pdev->params.dcbx_port_params.app.enabled, 1820 error,ets->enabled) && 1821 (!is_ets_dis_remote_tlv)) 1822 { 1823 DbgBreakIf(FALSE == pdev->params.dcbx_port_params.dcbx_enabled); 1824 pdev->params.dcbx_port_params.ets.enabled = TRUE; 1825 } 1826 else 1827 { 1828 1829 lm_dcbx_ets_disable(pdev); 1830 return; 1831 } 1832 1833 //Parse pg_pri_orginal_spread data and spread it from nibble to 32 bits 1834 lm_dcbx_get_ets_pri_pg_tbl(pdev, 1835 pg_pri_orginal_spread, 1836 ets->pri_pg_tbl, 1837 ARRSIZE(pg_pri_orginal_spread), 1838 DCBX_MAX_NUM_PRI_PG_ENTRIES); 1839 1840 lm_dcbx_cee_get_num_of_pg_traf_type(pdev, 1841 pg_pri_orginal_spread, 1842 &pg_help_data); 1843 1844 lm_dcbx_fill_cos_params(pdev, 1845 &pg_help_data, 1846 ets, 1847 pg_pri_orginal_spread); 1848 1849 } 1850 1851 /** 1852 * @description 1853 * Mapping between TC( acording to the given parameters from 1854 * upper layer) which isn't zero based to COS which is zero 1855 * based. 1856 * COS configuration is used to the chip configuration. 1857 * @param pdev 1858 * 1859 * @return STATIC void 1860 */ 1861 STATIC void 1862 lm_dcbx_ie_get_ets_ieee_feature( 1863 INOUT lm_device_t *pdev) 1864 { 1865 lm_dcbx_indicate_event_t *indicate_event = &pdev->dcbx_info.indicate_event; 1866 pg_params_t *ets_drv_param = &pdev->params.dcbx_port_params.ets; 1867 dcb_ets_tsa_param_t *ieee_ets = &indicate_event->ets_ieee_params_config; 1868 // COS should be continues and zero based 1869 u8_t cee_tc_to_continues_cos[DCBX_MAX_NUM_PRI_PG_ENTRIES] = {0}; 1870 u8_t i = 0; 1871 s16_t pri = 0; 1872 u8_t strict_pri = DCBX_S_PRI_COS_HIGHEST; 1873 u8_t tc_entry = 0; 1874 u8_t cos_entry = 0; 1875 const u8_t max_tc_sup = lm_dcbx_cos_max_num(pdev) ; 1876 u8_t next_free_cos_entry = 0; 1877 u8_t tc_used_bitmap = 0; 1878 #if (DBG) 1879 u8_t j = 0; 1880 u8_t pri_used_bitmap = 0; 1881 #endif //DBG 1882 /************************************ Validate Check ***************************/ 1883 ASSERT_STATIC(DCBX_MAX_NUM_PRI_PG_ENTRIES == DCBX_MAX_NUM_PG_BW_ENTRIES); 1884 ASSERT_STATIC(DCBX_MAX_NUM_PRI_PG_ENTRIES == ARRSIZE(ieee_ets->priority_assignment_table)); 1885 ASSERT_STATIC(DCBX_MAX_NUM_PG_BW_ENTRIES == ARRSIZE(ieee_ets->tc_bw_assignment_table)); 1886 ASSERT_STATIC(DCBX_MAX_NUM_PG_BW_ENTRIES == ARRSIZE(ieee_ets->tsa_assignment_table)); 1887 1888 DbgBreakIf(lm_dcbx_ets_ieee_config_not_valid == indicate_event->ets_ieee_config_state); 1889 /********************************** Init variables ***************************/ 1890 // Clean up old settings of ets on COS 1891 lm_dcbx_init_ets_internal_param(pdev, ets_drv_param); 1892 1893 // If application priority isn't enabled then all DCB features must be disabled. 1894 if((FALSE == pdev->params.dcbx_port_params.app.enabled)|| 1895 (LM_DCBX_IE_IS_ETS_DISABLE(ieee_ets->num_traffic_classes))|| 1896 (lm_dcbx_ets_ieee_config_en != indicate_event->ets_ieee_config_state)) 1897 { 1898 lm_dcbx_ets_disable(pdev); 1899 return; 1900 } 1901 1902 /*** Mapping between TC which isn't zero based to COS which is zero based*****/ 1903 1904 // Count the number of TC entries given and fill the appropriate COS entry. 1905 // The for is from the higher priority down, because higher priorities should 1906 // receive higher strict priority. 1907 for (pri = (ARRSIZE(ieee_ets->priority_assignment_table) -1); 1908 0 <= pri; 1909 pri--) 1910 { 1911 tc_entry = ieee_ets->priority_assignment_table[pri]; 1912 1913 if(0 == (tc_used_bitmap & (1 << tc_entry))) 1914 { 1915 // We should not reenter, this will cause a bug in strict priority. 1916 // Validate COS entry is legal 1917 if(max_tc_sup <= next_free_cos_entry ) 1918 { 1919 DbgBreakMsg(" Wrong ETS settings "); 1920 lm_dcbx_ets_disable(pdev); 1921 return; 1922 } 1923 1924 tc_used_bitmap |= (1 << tc_entry); 1925 cee_tc_to_continues_cos[tc_entry] = next_free_cos_entry; 1926 1927 if(TSA_ASSIGNMENT_DCB_TSA_STRICT == ieee_ets->tsa_assignment_table[tc_entry]) 1928 { 1929 ets_drv_param->cos_params[next_free_cos_entry].bw_tbl = DCBX_INVALID_COS_BW; 1930 ets_drv_param->cos_params[next_free_cos_entry].s_pri = strict_pri; 1931 // Prepare for next strict priority 1932 strict_pri = DCBX_S_PRI_COS_NEXT_LOWER_PRI(strict_pri); 1933 } 1934 else if(TSA_ASSIGNMENT_DCB_TSA_ETS == ieee_ets->tsa_assignment_table[tc_entry]) 1935 { 1936 ets_drv_param->cos_params[next_free_cos_entry].bw_tbl = ieee_ets->tc_bw_assignment_table[tc_entry]; 1937 ets_drv_param->cos_params[next_free_cos_entry].s_pri = DCBX_S_PRI_INVALID; 1938 } 1939 else 1940 { 1941 DbgBreakMsg("lm_dcbx_get_ets_ieee_feature parameters are check before " 1942 "this should not happen"); 1943 1944 lm_dcbx_ets_disable(pdev); 1945 return; 1946 } 1947 1948 // Prepare for next entry and also represents after this while the number 1949 // of used COS entries. 1950 next_free_cos_entry++; 1951 } 1952 } 1953 1954 // Fill priority to COS mapping 1955 for (pri = 0; pri < ARRSIZE(ieee_ets->priority_assignment_table); pri++) 1956 { 1957 tc_entry = ieee_ets->priority_assignment_table[pri]; 1958 cos_entry = cee_tc_to_continues_cos[tc_entry]; 1959 1960 DbgBreakIf(ARRSIZE(ets_drv_param->cos_params) <= cos_entry); 1961 1962 ets_drv_param->cos_params[cos_entry].pri_bitmask |= 1<< pri; 1963 1964 ets_drv_param->cos_params[cos_entry].pauseable = LM_DCBX_IS_PFC_PRI_SOME_PAUSE(pdev,ets_drv_param->cos_params[cos_entry].pri_bitmask); 1965 } 1966 1967 DbgBreakIf( ieee_ets->num_traffic_classes < next_free_cos_entry); 1968 1969 ets_drv_param->num_of_cos = (u8_t)next_free_cos_entry; 1970 ets_drv_param->enabled = TRUE; 1971 1972 #if (DBG) 1973 pri_used_bitmap = 0; 1974 for(i = 0 ; i < ets_drv_param->num_of_cos; i++) 1975 { 1976 // All priorities must be present 1977 pri_used_bitmap |= ets_drv_param->cos_params[i].pri_bitmask; 1978 for(j = i+1 ; j < ets_drv_param->num_of_cos; j++) 1979 { 1980 // Make sure there are no intersection 1981 DbgBreakIf(0 != (ets_drv_param->cos_params[i].pri_bitmask & 1982 ets_drv_param->cos_params[j].pri_bitmask)); 1983 } 1984 } 1985 DbgBreakIf(((1 << MAX_PFC_PRIORITIES) -1) != pri_used_bitmap); 1986 #endif //DBG 1987 } 1988 /** 1989 * @description 1990 * Fill priority to COS mapping. 1991 * @param pdev 1992 */ 1993 void 1994 lm_dcbx_fill_pri_to_cos_mapping(lm_device_t *pdev) 1995 { 1996 pg_params_t *ets_drv_param = &pdev->params.dcbx_port_params.ets; 1997 u8_t pri = 0; 1998 u8_t cos = 0; 1999 u8_t pri_bit = 0; 2000 2001 ASSERT_STATIC( MAX_PFC_PRIORITIES == ARRSIZE(pdev->dcbx_info.pri_to_cos)); 2002 2003 // Map all priorities to COS 0 by default 2004 mm_mem_zero(pdev->dcbx_info.pri_to_cos, sizeof(pdev->dcbx_info.pri_to_cos)); 2005 2006 if(FALSE == ets_drv_param->enabled) 2007 { 2008 return; 2009 } 2010 2011 // Fill the priority to COS 2012 for (cos = 0; cos < ets_drv_param->num_of_cos; cos++) 2013 { 2014 for( pri = 0; pri < ARRSIZE(pdev->dcbx_info.pri_to_cos) ; pri++) 2015 { 2016 pri_bit = 1 << pri; 2017 2018 if (ets_drv_param->cos_params[cos].pri_bitmask & pri_bit) 2019 { 2020 pdev->dcbx_info.pri_to_cos[pri] = cos; 2021 } 2022 } 2023 } 2024 } 2025 2026 static void lm_dcbx_map_nw(INOUT lm_device_t *pdev) 2027 { 2028 u8_t i; 2029 u32_t unmapped = (1 << MAX_PFC_PRIORITIES) - 1; // all ones 2030 u32_t *ttp = pdev->params.dcbx_port_params.app.traffic_type_priority; 2031 u32_t nw_prio = 1 << ttp[LLFC_TRAFFIC_TYPE_NW]; 2032 dcbx_cos_params_t *cos_params = 2033 pdev->params.dcbx_port_params.ets.cos_params; 2034 2035 // get unmapped priorities by clearing mapped bits 2036 for (i = 0; i < LLFC_DRIVER_TRAFFIC_TYPE_MAX; i++) 2037 unmapped &= ~(1 << ttp[i]); 2038 2039 // find cos for nw prio and extend it with unmapped 2040 for (i = 0; i < ARRSIZE(pdev->params.dcbx_port_params.ets.cos_params); i++) { 2041 if (cos_params[i].pri_bitmask & nw_prio) { 2042 // extend the bitmask with unmapped 2043 DbgMessage(pdev, INFORM, 2044 "cos %d extended with 0x%08x", i, unmapped); 2045 2046 cos_params[i].pri_bitmask |= unmapped; 2047 break; 2048 } 2049 } 2050 } 2051 /** 2052 * Pass on all priority_assignment_table cells and merge them to 2053 * the first cell of the BW until the amount of cells will be 2054 * less than max_tc_sup 2055 * 2056 * @param pdev 2057 * @param ieee_ets 2058 */ 2059 void 2060 lm_dcbx_ie_merge_bw_cells( 2061 INOUT lm_device_t *pdev, 2062 INOUT dcb_ets_tsa_param_t *ieee_ets 2063 ) 2064 { 2065 const u8_t max_tc_sup = lm_dcbx_cos_max_num(pdev); 2066 const u8_t invalid_tc = ARRSIZE(ieee_ets->priority_assignment_table); 2067 u8_t tc_entry = 0; 2068 u8_t tc_entry_bit = 0; 2069 u8_t merge_tc = invalid_tc; 2070 u8_t pri = 0; 2071 u8_t pri_remap = 0; 2072 u8_t tc_used_bitmap = 0; 2073 2074 if(ieee_ets->num_traffic_classes <= max_tc_sup) 2075 { 2076 // nothing to do. 2077 return; 2078 } 2079 2080 for (pri = 0; 2081 pri < ARRSIZE(ieee_ets->priority_assignment_table); 2082 pri++) 2083 { 2084 tc_entry = ieee_ets->priority_assignment_table[pri]; 2085 tc_entry_bit = (1 << tc_entry); 2086 2087 if((0 == (tc_used_bitmap & tc_entry_bit)) && 2088 (TSA_ASSIGNMENT_DCB_TSA_ETS == ieee_ets->tsa_assignment_table[tc_entry])) 2089 { 2090 if(invalid_tc != merge_tc) 2091 { 2092 // We found already a cell to merge to 2093 DbgBreakIf(tc_entry == merge_tc); 2094 2095 // point the pri to merge_tc. 2096 ieee_ets->priority_assignment_table[pri] = merge_tc; 2097 2098 // merge the cells 2099 ieee_ets->tc_bw_assignment_table[merge_tc] += ieee_ets->tc_bw_assignment_table[tc_entry]; 2100 ieee_ets->tc_bw_assignment_table[tc_entry] = 0; 2101 ieee_ets->tsa_assignment_table[tc_entry] = TSA_ASSIGNMENT_DCB_TSA_STRICT;// Don't care 2102 2103 // remapping all tc_entry => merge_tc 2104 for (pri_remap = 0; 2105 pri_remap < ARRSIZE(ieee_ets->priority_assignment_table); 2106 pri_remap++) 2107 { 2108 if(tc_entry == ieee_ets->priority_assignment_table[pri_remap]) 2109 { 2110 ieee_ets->priority_assignment_table[pri_remap] = merge_tc; 2111 } 2112 } 2113 2114 ieee_ets->num_traffic_classes--; 2115 } 2116 else 2117 { 2118 // Find first BW cell 2119 merge_tc = tc_entry; 2120 } 2121 } 2122 2123 tc_used_bitmap |= tc_entry_bit; 2124 2125 if(ieee_ets->num_traffic_classes <= max_tc_sup ) 2126 { 2127 break; 2128 } 2129 2130 } 2131 2132 DbgBreakIf(max_tc_sup < ieee_ets->num_traffic_classes); 2133 2134 } 2135 /** 2136 * if (admin.ETS == local.ETS) 2137 * Use OS configuration. 2138 * Else 2139 * Parse the data from CEE to IEEE . 2140 * @param pdev 2141 * @param cee_ets 2142 * 2143 * @return u8_t 2144 */ 2145 u8_t 2146 lm_dcbx_ie_is_ets_admin_eq_local( 2147 INOUT lm_device_t *pdev, 2148 IN dcbx_ets_feature_t *cee_ets 2149 ) 2150 { 2151 lldp_admin_mib_t admin_mib = {0}; 2152 u32_t admin_mib_offset = 0; 2153 lm_status_t lm_status = LM_STATUS_SUCCESS; 2154 2155 lm_status = lm_dcbx_read_admin_mib( pdev, 2156 &admin_mib, 2157 &admin_mib_offset); 2158 2159 if(LM_STATUS_SUCCESS != lm_status) 2160 { 2161 DbgBreakMsg(" lm_dcbx_ie_admin_mib_updated_runtime lm_dcbx_read_admin_mib failed "); 2162 return FALSE; 2163 } 2164 2165 return mm_memcmp(cee_ets, 2166 &admin_mib.features.ets, 2167 sizeof(admin_mib.features.ets)); 2168 2169 } 2170 /** 2171 In CEE all strict TC-s are map to PGID=15. This is how it 2172 will appear in the TLV on the wire and in local settings. 2173 As a result there is a problem in showing the correct 2174 strict TC settings of the local and remote peer side (remote 2175 configuration): a. If more than one TC (e.g. TC_0 and TC_1) 2176 will be assigned to TSA strict, on the local or remote peer 2177 side they will be merged to one TC. b. The strict TC number 2178 will not be correct on the local and remote peer side. 2179 2180 Assumption:In ETS there is no merging done by MCP we either 2181 take our configuration or the other side 2182 2183 Suggested solution: Driver will save ETS OS 2184 configuration. 2185 2186 In case of an interrupt driver will : 2187 if (admin.ETS == local.ETS) 2188 Use OS configuration. 2189 Else 2190 Parse the data from CEE to IEEE . 2191 * @param pdev 2192 * @param cee_ets 2193 */ 2194 void 2195 lm_dcbx_ie_get_ieee_config_param( 2196 INOUT lm_device_t *pdev, 2197 IN dcbx_ets_feature_t *cee_ets, 2198 IN const u32_t error 2199 ) 2200 { 2201 lm_dcbx_indicate_event_t *indicate_event = &pdev->dcbx_info.indicate_event; 2202 u32_t flags = 0; 2203 2204 if(FALSE == DCBX_MIB_IS_ETS_ENABLED(pdev->params.dcbx_port_params.app.enabled, 2205 error,cee_ets->enabled)) 2206 { 2207 indicate_event->ets_ieee_config_state = lm_dcbx_ets_ieee_config_di; 2208 mm_mem_zero(&indicate_event->ets_ieee_params_config, 2209 sizeof(indicate_event->ets_ieee_params_os)); 2210 return; 2211 } 2212 2213 if(lm_dcbx_ie_is_ets_admin_eq_local(pdev,cee_ets) && 2214 indicate_event->is_ets_ieee_params_os_valid) 2215 { 2216 indicate_event->ets_ieee_config_state = lm_dcbx_ets_ieee_config_en; 2217 2218 mm_memcpy(&indicate_event->ets_ieee_params_config, 2219 &indicate_event->ets_ieee_params_os, 2220 sizeof(indicate_event->ets_ieee_params_os)); 2221 } 2222 else 2223 { 2224 lm_dcbx_ie_ets_cee_to_ieee_unparse(pdev, 2225 cee_ets, 2226 &indicate_event->ets_ieee_params_config, 2227 &flags); 2228 2229 if(GET_FLAGS(flags,DCB_PARAMS_ETS_ENABLED)) 2230 { 2231 indicate_event->ets_ieee_config_state = lm_dcbx_ets_ieee_config_en; 2232 } 2233 else 2234 { 2235 indicate_event->ets_ieee_config_state = lm_dcbx_ets_ieee_config_di; 2236 } 2237 2238 lm_dcbx_ie_merge_bw_cells(pdev, 2239 &indicate_event->ets_ieee_params_config); 2240 } 2241 } 2242 2243 /** 2244 * @description 2245 * 2246 * @param pdev 2247 * @param pfc 2248 * @param error 2249 * 2250 * @return STATIC void 2251 */ 2252 STATIC void 2253 lm_dcbx_get_ets_feature( 2254 INOUT lm_device_t *pdev, 2255 IN dcbx_ets_feature_t *ets, 2256 IN const u32_t error 2257 ) 2258 { 2259 lm_dcbx_indicate_event_t *indicate_event = &pdev->dcbx_info.indicate_event; 2260 2261 if(lm_dcbx_ets_config_state_cee == indicate_event->ets_config_state) 2262 { 2263 indicate_event->ets_ieee_config_state = lm_dcbx_ets_ieee_config_not_valid; 2264 2265 lm_dcbx_get_ets_cee_feature( 2266 pdev, 2267 ets, 2268 error); 2269 2270 lm_dcbx_map_nw(pdev); 2271 2272 DbgBreakIf(lm_dcbx_ets_ieee_config_not_valid != indicate_event->ets_ieee_config_state); 2273 } 2274 else 2275 { 2276 lm_dcbx_ie_get_ieee_config_param(pdev, 2277 ets, 2278 error); 2279 2280 //If ets is given from upper layer we don't use chip ETS configuration 2281 lm_dcbx_ie_get_ets_ieee_feature( pdev); 2282 2283 DbgBreakIf(lm_dcbx_ets_ieee_config_not_valid == indicate_event->ets_ieee_config_state); 2284 } 2285 2286 lm_dcbx_fill_pri_to_cos_mapping( pdev); 2287 } 2288 /******************************************************************************* 2289 * Description: 2290 * 2291 * Return: 2292 ******************************************************************************/ 2293 STATIC void 2294 lm_dcbx_get_pfc_feature( 2295 INOUT lm_device_t *pdev, 2296 IN const dcbx_pfc_feature_t *pfc, 2297 IN const u32_t error 2298 ) 2299 { 2300 const u8_t is_pfc_dis_remote_tlv = lm_dcbx_is_feature_dis_remote_tlv( 2301 pdev, 2302 error, 2303 DCBX_REMOTE_PFC_TLV_NOT_FOUND); 2304 2305 if(DCBX_MIB_IS_PFC_ENABLED(pdev->params.dcbx_port_params.app.enabled, 2306 error, pfc->enabled) && (!is_pfc_dis_remote_tlv)) 2307 { 2308 DbgBreakIf(FALSE == pdev->params.dcbx_port_params.dcbx_enabled); 2309 pdev->params.dcbx_port_params.pfc.enabled = TRUE; 2310 pdev->params.dcbx_port_params.pfc.priority_non_pauseable_mask = (u8_t)(~(pfc->pri_en_bitmap)); 2311 } 2312 else 2313 { 2314 pdev->params.dcbx_port_params.pfc.enabled = FALSE; 2315 pdev->params.dcbx_port_params.pfc.priority_non_pauseable_mask = 0; 2316 } 2317 2318 } 2319 2320 /******************************************************************************* 2321 * Description: Take the highest priority available.(This function don't do the 2322 * initialization of priority.) 2323 * 2324 * Return: 2325 ******************************************************************************/ 2326 STATIC void 2327 lm_dcbx_get_ap_priority( 2328 IN lm_device_t *pdev, 2329 INOUT u32_t *entry_pri, 2330 IN const u8_t pri_bitmap, 2331 INOUT u8_t *is_default_off_tt_set 2332 ) 2333 { 2334 u8_t pri = MAX_PFC_PRIORITIES; 2335 u8_t index = 0 ; 2336 u8_t pri_mask = 0; 2337 2338 //Chose the highest priority the lower pri will get run over 2339 for(index = 0; index < MAX_PFC_PRIORITIES ; index++) 2340 { 2341 pri_mask = 1 <<(index); 2342 if(GET_FLAGS(pri_bitmap , pri_mask)) 2343 { 2344 pri = index ; 2345 } 2346 } 2347 2348 if(pri < MAX_PFC_PRIORITIES) 2349 { 2350 if((*entry_pri < MAX_PFC_PRIORITIES) && 2351 (FALSE == *is_default_off_tt_set)) 2352 { 2353 *entry_pri = max(*entry_pri, pri); 2354 } 2355 else 2356 { 2357 *entry_pri = pri; 2358 *is_default_off_tt_set = FALSE; 2359 } 2360 2361 } 2362 } 2363 /** 2364 * Check if the entry is an ISCSI classification entry. 2365 * @param app_id 2366 * @param appBitfield 2367 * 2368 * @return STATIC u8_t 2369 */ 2370 STATIC u8_t 2371 lm_dcbx_cee_is_entry_iscsi_classif(IN const u8_t appBitfield, 2372 IN const u16_t app_id) 2373 { 2374 if(GET_FLAGS(appBitfield,DCBX_APP_SF_PORT) && 2375 (TCP_PORT_ISCSI == app_id)) 2376 { 2377 return TRUE; 2378 } 2379 2380 return FALSE; 2381 } 2382 /** 2383 * Check if the entry is an FCOE classification entry. 2384 * @param app_id 2385 * @param appBitfield 2386 * 2387 * @return STATIC u8_t 2388 */ 2389 STATIC u8_t 2390 lm_dcbx_cee_is_entry_fcoe_classif(IN const u8_t appBitfield, 2391 IN const u16_t app_id) 2392 { 2393 if(GET_FLAGS(appBitfield,DCBX_APP_SF_ETH_TYPE) && 2394 (ETH_TYPE_FCOE == app_id)) 2395 { 2396 return TRUE; 2397 } 2398 2399 return FALSE; 2400 } 2401 2402 /** 2403 * Look for offload app priorities for offload traffic 2404 * types:ISCSI and FCOE. 2405 * @param pdev 2406 * @param app_tbl 2407 * @param app_tbl_size 2408 * 2409 * @return STATIC void 2410 */ 2411 STATIC void 2412 lm_dcbx_get_app_pri_off_tt( 2413 lm_device_t *pdev, 2414 IN const dcbx_app_priority_entry_t *app_tbl, 2415 IN const u8_t app_tbl_size, 2416 INOUT u8_t *is_default_off_tt_used 2417 ) 2418 { 2419 u8_t index = 0; 2420 2421 for(index = 0 ;(index < app_tbl_size); index++) 2422 { 2423 if(DCBX_APP_ENTRY_VALID != GET_FLAGS(app_tbl[index].appBitfield,DCBX_APP_ENTRY_VALID)) 2424 { 2425 continue; 2426 } 2427 2428 if(lm_dcbx_cee_is_entry_fcoe_classif(app_tbl[index].appBitfield, app_tbl[index].app_id)) 2429 { 2430 lm_dcbx_get_ap_priority(pdev, 2431 &(pdev->params.dcbx_port_params.app.traffic_type_priority[LLFC_TRAFFIC_TYPE_FCOE]), 2432 app_tbl[index].pri_bitmap, 2433 &is_default_off_tt_used[LLFC_TRAFFIC_TYPE_FCOE]); 2434 } 2435 2436 if(lm_dcbx_cee_is_entry_iscsi_classif(app_tbl[index].appBitfield, app_tbl[index].app_id)) 2437 { 2438 lm_dcbx_get_ap_priority(pdev, 2439 &(pdev->params.dcbx_port_params.app.traffic_type_priority[LLFC_TRAFFIC_TYPE_ISCSI]), 2440 app_tbl[index].pri_bitmap, 2441 &is_default_off_tt_used[LLFC_TRAFFIC_TYPE_ISCSI]); 2442 } 2443 } 2444 } 2445 /** 2446 * Update non negotiation application IDs entries. 2447 * @param pdev 2448 * 2449 * @return STATIC void 2450 */ 2451 STATIC void 2452 lm_dcbx_get_app_pri_off_tt_non_neg( 2453 INOUT lm_device_t *pdev, 2454 INOUT u8_t *is_default_off_tt_set) 2455 { 2456 lm_dcbx_indicate_event_t *indicate_event = &pdev->dcbx_info.indicate_event; 2457 // If indicate event is enabled and there is a OS configuration contained an entry 2458 // with �TCP port� = 3260 use that entry. 2459 if((TRUE == pdev->dcbx_info.is_indicate_event_en) && 2460 (LM_DCBX_ILLEGAL_PRI != indicate_event->iscsi_tcp_pri)) 2461 { 2462 pdev->params.dcbx_port_params.app.traffic_type_priority[LLFC_TRAFFIC_TYPE_ISCSI] = 2463 indicate_event->iscsi_tcp_pri; 2464 2465 is_default_off_tt_set[LLFC_TRAFFIC_TYPE_ISCSI] = FALSE; 2466 } 2467 } 2468 /******************************************************************************* 2469 * Description: 2470 * Traffic type (protocol) identification: 2471 * Networking is identified by Ether-Type = IPv4 or Ether-Type =IPv6. 2472 * iSCSI is by TCP-port = iSCSI well know port (3260) 2473 * FCoE is identified by Ether-type = FCoE 2474 * Theoretically each protocol can be associated with multiple priorities (a priority bit map). In this case we choose the highest one. 2475 * Priority assignment for networking: 2476 * 1. If IPv4 is identified, the networking priority is the IPv4 priority (highest one as mentioned above). 2477 * 2. Otherwise if IPv6 is identified, the networking priority is the IPv6 priority. 2478 * 3. Otherwise the networking priority is set 0. (All other protocol TLVs which are not iSCSI or FCoE are ignored). 2479 * 2480 * Priority assignment for iSCSI: 2481 * 1. If the operational configuration from MCP contains an entry with 'TCP or UDP port' = 3260 use that entry, 2482 * 2. Else if OS configuration contained an entry with 'TCP port' = 3260 use that entry, 2483 * 3. Else use the default configuration. 2484 * 2485 * Priority assignment for FCoE: 2486 * 1. If FCoE is identified, then obviously this is the FCoE priority (again the highest one). 2487 * 2. Otherwise FCoE priority is set to default configuration. 2488 * Return: 2489 ******************************************************************************/ 2490 STATIC void 2491 lm_dcbx_get_ap_feature( 2492 INOUT lm_device_t *pdev, 2493 IN const dcbx_app_priority_feature_t *app, 2494 IN const dcbx_app_priority_entry_t *app_tbl_ext, 2495 IN const u8_t app_tbl_ext_size, 2496 IN const u32_t error) 2497 { 2498 u8_t index = 0; 2499 u8_t const default_pri = (app->default_pri < MAX_PFC_PRIORITIES)? app->default_pri: 0; 2500 u8_t is_default_off_tt_used[MAX_TRAFFIC_TYPE] = {0}; 2501 const u8_t is_app_dis_remote_tlv = lm_dcbx_is_feature_dis_remote_tlv( 2502 pdev, 2503 error, 2504 DCBX_REMOTE_APP_TLV_NOT_FOUND); 2505 2506 if((TRUE == pdev->params.dcbx_port_params.dcbx_enabled) && 2507 DCBX_MIB_IS_APP_ENABLED(app->enabled, error) && (!is_app_dis_remote_tlv)) 2508 { 2509 pdev->params.dcbx_port_params.app.enabled = TRUE; 2510 2511 // First initialize all the entries to default priority 2512 for( index=0 ; index < ARRSIZE(pdev->params.dcbx_port_params.app.traffic_type_priority) ;index++) 2513 { 2514 is_default_off_tt_used[index] = TRUE; 2515 pdev->params.dcbx_port_params.app.traffic_type_priority[index] = default_pri; 2516 } 2517 // The value of this entries is used only if there isn't a corresponding negotiated entry. 2518 lm_dcbx_get_app_pri_off_tt_non_neg(pdev, is_default_off_tt_used); 2519 2520 lm_dcbx_get_app_pri_off_tt(pdev, 2521 app->app_pri_tbl, 2522 ARRSIZE(app->app_pri_tbl), 2523 is_default_off_tt_used); 2524 2525 lm_dcbx_get_app_pri_off_tt(pdev, 2526 app_tbl_ext, 2527 app_tbl_ext_size, 2528 is_default_off_tt_used); 2529 } 2530 else 2531 { 2532 pdev->params.dcbx_port_params.app.enabled = FALSE; 2533 for( index=0 ; 2534 index < ARRSIZE(pdev->params.dcbx_port_params.app.traffic_type_priority) ; 2535 index++) 2536 { 2537 pdev->params.dcbx_port_params.app.traffic_type_priority[index] = 2538 INVALID_TRAFFIC_TYPE_PRIORITY; 2539 } 2540 } 2541 } 2542 void 2543 lm_dcbx_get_dcbx_enabled( 2544 INOUT lm_device_t *pdev, 2545 IN const u32_t error) 2546 { 2547 dcbx_port_params_t *dcbx_port_params = &(pdev->params.dcbx_port_params); 2548 u8_t const mfw_config = lm_dcbx_check_drv_flags(pdev, DRV_FLAGS_DCB_MFW_CONFIGURED); 2549 2550 if((0 == GET_FLAGS(error, DCBX_REMOTE_MIB_ERROR)) || 2551 (TRUE == mfw_config)) 2552 { 2553 dcbx_port_params->dcbx_enabled = TRUE; 2554 } 2555 else 2556 { 2557 //If no configuration from OS / BACS and no DCBX received from the peer then disable DCB. 2558 dcbx_port_params->dcbx_enabled = FALSE; 2559 } 2560 } 2561 /******************************************************************************* 2562 * Description: Translate PFC/PG parameters to VBD parameters and call relevent 2563 * Function to set the parameters. 2564 * 2565 * Return: 2566 ******************************************************************************/ 2567 STATIC void 2568 lm_print_dcbx_drv_param(IN struct _lm_device_t *pdev, 2569 IN const lldp_local_mib_t *local_mib) 2570 { 2571 #if DBG 2572 u8_t i =0; 2573 DbgMessage(pdev, INFORM, "local_mib.error %x\n",local_mib->error); 2574 2575 //Pg 2576 DbgMessage(pdev, INFORM, "local_mib.features.ets.enabled %x\n",local_mib->features.ets.enabled); 2577 for(i=0;i<DCBX_MAX_NUM_PG_BW_ENTRIES;i++) 2578 { 2579 DbgMessage(pdev, INFORM, "local_mib.features.ets.pg_bw_tbl[%x] %x\n",i,DCBX_PG_BW_GET(local_mib->features.ets.pg_bw_tbl,i)); 2580 } 2581 for(i=0;i<DCBX_MAX_NUM_PRI_PG_ENTRIES;i++) 2582 { 2583 DbgMessage(pdev, INFORM,"local_mib.features.ets.pri_pg_tbl[%x] %x\n",i,DCBX_PRI_PG_GET(local_mib->features.ets.pri_pg_tbl,i)); 2584 } 2585 2586 //pfc 2587 DbgMessage(pdev, INFORM, "local_mib.features.pfc.pri_en_bitmap %x\n",local_mib->features.pfc.pri_en_bitmap); 2588 DbgMessage(pdev, INFORM, "local_mib.features.pfc.pfc_caps %x\n",local_mib->features.pfc.pfc_caps); 2589 DbgMessage(pdev, INFORM, "local_mib.features.pfc.enabled %x\n",local_mib->features.pfc.enabled); 2590 2591 DbgMessage(pdev, INFORM, "local_mib.features.app.default_pri %x\n",local_mib->features.app.default_pri); 2592 DbgMessage(pdev, INFORM, "local_mib.features.app.tc_supported %x\n",local_mib->features.app.tc_supported); 2593 DbgMessage(pdev, INFORM, "local_mib.features.app.enabled %x\n",local_mib->features.app.enabled); 2594 for(i=0;i<DCBX_MAX_APP_PROTOCOL;i++) 2595 { 2596 2597 // This has no logic this is only done for supporting old bootcodes. 2598 // The boot code still expexts u8 [2] instead of u16 2599 DbgMessage(pdev, INFORM,"local_mib.features.app.app_pri_tbl[%x].app_id %x\n", 2600 i,local_mib->features.app.app_pri_tbl[i].app_id); 2601 2602 DbgMessage(pdev, INFORM, "local_mib.features.app.app_pri_tbl[%x].pri_bitmap %x\n", 2603 i,local_mib->features.app.app_pri_tbl[i].pri_bitmap); 2604 DbgMessage(pdev, INFORM, "local_mib.features.app.app_pri_tbl[%x].appBitfield %x\n", 2605 i,local_mib->features.app.app_pri_tbl[i].appBitfield); 2606 } 2607 #endif 2608 } 2609 /******************************************************************************* 2610 * Description: Translate PFC/PG parameters to VBD parameters and call relevent 2611 * Function to set the parameters. 2612 * 2613 * Return: 2614 ******************************************************************************/ 2615 STATIC void 2616 lm_get_dcbx_drv_param(INOUT lm_device_t *pdev, 2617 IN lldp_local_mib_t *local_mib, 2618 IN const lldp_local_mib_ext_t *local_mib_ext) 2619 { 2620 if(CHK_NULL(local_mib) || CHK_NULL(local_mib_ext)) 2621 { 2622 DbgBreakMsg("lm_get_dcbx_drv_param wrong in parameters "); 2623 return; 2624 } 2625 2626 lm_dcbx_get_dcbx_enabled( 2627 pdev, 2628 local_mib->error); 2629 2630 lm_dcbx_get_ap_feature( 2631 pdev, 2632 &(local_mib->features.app), 2633 local_mib_ext->app_pri_tbl_ext, 2634 ARRSIZE(local_mib_ext->app_pri_tbl_ext), 2635 local_mib->error); 2636 2637 lm_dcbx_get_pfc_feature( 2638 pdev, 2639 &(local_mib->features.pfc), 2640 local_mib->error); 2641 2642 lm_dcbx_get_ets_feature( 2643 pdev, 2644 &(local_mib->features.ets), 2645 local_mib->error); 2646 } 2647 /******************************************************************************* 2648 * Description: Should be integrate with write and moved to common code 2649 * 2650 * Return: 2651 ******************************************************************************/ 2652 STATIC void 2653 lm_dcbx_read_shmem2_mcp_fields(struct _lm_device_t * pdev, 2654 u32_t offset, 2655 u32_t * val) 2656 { 2657 u32_t shmem2_size; 2658 2659 if (pdev->hw_info.shmem_base2 != 0) 2660 { 2661 LM_SHMEM2_READ(pdev, OFFSETOF(shmem2_region_t,size), &shmem2_size); 2662 if (shmem2_size > offset) 2663 { 2664 LM_SHMEM2_READ(pdev, offset, val); 2665 } 2666 } 2667 } 2668 2669 /******************************************************************************* 2670 * Description:Should be integrate with read and moved to common code 2671 * 2672 * Return: 2673 ******************************************************************************/ 2674 STATIC void 2675 lm_dcbx_write_shmem2_mcp_fields(struct _lm_device_t *pdev, 2676 u32_t offset, 2677 u32_t val) 2678 { 2679 u32_t shmem2_size; 2680 2681 if (pdev->hw_info.shmem_base2 != 0) 2682 { 2683 LM_SHMEM2_READ(pdev, OFFSETOF(shmem2_region_t,size), &shmem2_size); 2684 if (shmem2_size > offset) 2685 { 2686 LM_SHMEM2_WRITE(pdev, offset, val); 2687 } 2688 } 2689 } 2690 /******************************************************************************* 2691 * Description: 2692 * 2693 * Return: 2694 ******************************************************************************/ 2695 STATIC void 2696 lm_dcbx_stop_hw_tx(struct _lm_device_t * pdev) 2697 { 2698 2699 // TODO DCBX change to cmd_id 2700 lm_eq_ramrod_post_sync(pdev, 2701 RAMROD_CMD_ID_COMMON_STOP_TRAFFIC, 2702 0, 2703 CMD_PRIORITY_MEDIUM,/* Called from WI must be done ASAP*/ 2704 &(pdev->dcbx_info.dcbx_ramrod_state), 2705 FUNCTION_DCBX_STOP_POSTED, 2706 FUNCTION_DCBX_STOP_COMPLETED); 2707 2708 } 2709 /******************************************************************************* 2710 * Description: 2711 * 2712 * Return: 2713 ******************************************************************************/ 2714 STATIC void 2715 lm_dcbx_resume_hw_tx(struct _lm_device_t * pdev) 2716 { 2717 lm_dcbx_fw_struct(pdev); 2718 2719 lm_eq_ramrod_post_sync(pdev, 2720 RAMROD_CMD_ID_COMMON_START_TRAFFIC, 2721 pdev->dcbx_info.pfc_fw_cfg_phys.as_u64, 2722 CMD_PRIORITY_HIGH,/* Called from WI must be done ASAP*/ 2723 &(pdev->dcbx_info.dcbx_ramrod_state), 2724 FUNCTION_DCBX_START_POSTED, 2725 FUNCTION_DCBX_START_COMPLETED); 2726 2727 } 2728 /******************************************************************************* 2729 * Description: 2730 * 2731 * Return: 2732 ******************************************************************************/ 2733 #define DCBX_LOCAL_MIB_MAX_TRY_READ (100) 2734 STATIC lm_status_t 2735 lm_dcbx_read_remote_local_mib(IN struct _lm_device_t *pdev, 2736 OUT u32_t *base_mib_addr, 2737 IN const dcbx_read_mib_type read_mib_type) 2738 { 2739 static const u8_t dcbx_local_mib_max_try_read = DCBX_LOCAL_MIB_MAX_TRY_READ; 2740 u8_t max_try_read = 0 ,i =0; 2741 u32_t * buff = NULL; 2742 u32_t mib_size = 0,prefix_seq_num = 0 ,suffix_seq_num = 0; 2743 lldp_remote_mib_t *remote_mib = NULL; 2744 lldp_local_mib_t *local_mib = NULL; 2745 const u32_t mcp_dcbx_neg_res_offset = OFFSETOF(shmem2_region_t,dcbx_neg_res_offset); 2746 const u32_t mcp_dcbx_remote_mib_offset = OFFSETOF(shmem2_region_t,dcbx_remote_mib_offset); 2747 u32_t offset = 0; 2748 // verify no wraparound on while loop 2749 ASSERT_STATIC( sizeof( max_try_read ) == sizeof(u8_t) ); 2750 ASSERT_STATIC(DCBX_LOCAL_MIB_MAX_TRY_READ < ((u8_t)-1)); 2751 2752 switch (read_mib_type) 2753 { 2754 case DCBX_READ_LOCAL_MIB: 2755 2756 // Get negotiation results MIB data 2757 offset = SHMEM_DCBX_NEG_RES_NONE; 2758 2759 lm_dcbx_read_shmem2_mcp_fields(pdev, 2760 mcp_dcbx_neg_res_offset, 2761 &offset); 2762 2763 if (SHMEM_DCBX_NEG_RES_NONE == offset) 2764 { 2765 DbgBreakMsg("lm_dcbx_read_remote_local_mib DCBX Negotiation result not supported"); 2766 return LM_STATUS_FAILURE; 2767 } 2768 mib_size = sizeof(lldp_local_mib_t); 2769 break; 2770 case DCBX_READ_REMOTE_MIB: 2771 // Get remote MIB data 2772 offset = SHMEM_DCBX_REMOTE_MIB_NONE; 2773 2774 lm_dcbx_read_shmem2_mcp_fields(pdev, 2775 mcp_dcbx_remote_mib_offset, 2776 &offset); 2777 2778 if (SHMEM_DCBX_REMOTE_MIB_NONE == offset) 2779 { 2780 DbgBreakMsg("lm_dcbx_read_remote_local_mib DCBX Negotiation result not supported"); 2781 return LM_STATUS_FAILURE; 2782 } 2783 2784 mib_size = sizeof(lldp_remote_mib_t); 2785 break; 2786 default: 2787 DbgBreakIf(1); 2788 return LM_STATUS_FAILURE; 2789 } 2790 2791 offset += PORT_ID(pdev) * mib_size; 2792 2793 do 2794 { 2795 buff = base_mib_addr; 2796 2797 for(i=0 ;i<mib_size; i+=4,buff++) 2798 { 2799 *buff = REG_RD(pdev, 2800 offset + i); 2801 } 2802 max_try_read++; 2803 2804 switch (read_mib_type) 2805 { 2806 case DCBX_READ_LOCAL_MIB: 2807 local_mib = (lldp_local_mib_t *) base_mib_addr; 2808 prefix_seq_num = local_mib->prefix_seq_num; 2809 suffix_seq_num = local_mib->suffix_seq_num; 2810 break; 2811 case DCBX_READ_REMOTE_MIB: 2812 remote_mib = (lldp_remote_mib_t *) base_mib_addr; 2813 prefix_seq_num = remote_mib->prefix_seq_num; 2814 suffix_seq_num = remote_mib->suffix_seq_num; 2815 break; 2816 default: 2817 DbgBreakIf(1); 2818 return LM_STATUS_FAILURE; 2819 } 2820 }while((prefix_seq_num != suffix_seq_num)&& 2821 (max_try_read <dcbx_local_mib_max_try_read)); 2822 2823 2824 if(max_try_read >= dcbx_local_mib_max_try_read) 2825 { 2826 DbgBreakMsg("prefix_seq_num doesnt equal suffix_seq_num for to much time"); 2827 return LM_STATUS_FAILURE; 2828 } 2829 return LM_STATUS_SUCCESS; 2830 } 2831 /** 2832 * 2833 * @param pdev 2834 * @param local_mib 2835 * @param local_mib_ext 2836 * 2837 * @return lm_status_t 2838 */ 2839 lm_status_t 2840 lm_dcbx_read_local_mib_fields( 2841 IN struct _lm_device_t *pdev, 2842 OUT lldp_local_mib_t *local_mib, 2843 OUT lldp_local_mib_ext_t *local_mib_ext) 2844 { 2845 const u32_t field_res_ext_offset = OFFSETOF(shmem2_region_t,dcbx_neg_res_ext_offset); 2846 u32_t res_ext_offset = SHMEM_DCBX_NEG_RES_EXT_NONE; 2847 u8_t is_ext_sup = FALSE; 2848 u8_t max_try_read = 0; 2849 lm_status_t lm_status = LM_STATUS_SUCCESS; 2850 2851 mm_mem_zero(local_mib, sizeof(lldp_local_mib_t)); 2852 mm_mem_zero(local_mib_ext, sizeof(lldp_local_mib_ext_t)); 2853 2854 if(LM_SHMEM2_HAS(pdev, dcbx_neg_res_ext_offset)) 2855 { 2856 lm_dcbx_read_shmem2_mcp_fields(pdev, 2857 field_res_ext_offset, 2858 &res_ext_offset); 2859 //CQ62832 - T7.0 bootcode contains the field dcbx_neg_res_ext_offset 2860 // in shmem2 but dcbx_neg_res_ext_offse isn't implemented. 2861 if (SHMEM_DCBX_NEG_RES_EXT_NONE != res_ext_offset) 2862 { 2863 res_ext_offset += PORT_ID(pdev) * sizeof(lldp_local_mib_ext_t); 2864 is_ext_sup = TRUE; 2865 } 2866 } 2867 2868 do 2869 { 2870 lm_status = lm_dcbx_read_remote_local_mib(pdev, 2871 (u32_t *)local_mib, 2872 DCBX_READ_LOCAL_MIB); 2873 if (LM_STATUS_SUCCESS != lm_status) 2874 { 2875 DbgBreakMsg("lm_dcbx_read_remote_local_mib DCBX Negotiation result not supported"); 2876 return lm_status; 2877 } 2878 2879 if(FALSE == is_ext_sup) 2880 { 2881 break; 2882 } 2883 2884 lm_reg_rd_blk(pdev, 2885 res_ext_offset, 2886 (u32_t *)local_mib_ext, 2887 (sizeof(lldp_local_mib_ext_t)/sizeof(u32_t))); 2888 2889 if((local_mib->prefix_seq_num == local_mib->suffix_seq_num ) && 2890 (local_mib_ext->prefix_seq_num == local_mib_ext->suffix_seq_num ) && 2891 (local_mib_ext->suffix_seq_num == local_mib->suffix_seq_num )) 2892 { 2893 break; 2894 } 2895 2896 max_try_read++; 2897 2898 }while(max_try_read < DCBX_LOCAL_MIB_MAX_TRY_READ); 2899 2900 2901 if(max_try_read >= DCBX_LOCAL_MIB_MAX_TRY_READ) 2902 { 2903 DbgBreakMsg("lm_dcbx_read_local_mib_fields : prefix_seq_num doesnt equal suffix_seq_num for to much time"); 2904 return LM_STATUS_FAILURE; 2905 } 2906 2907 return lm_status; 2908 } 2909 /** 2910 * Use parameters given for first calculate VBD settings for 2911 * each feature. 2912 * Use VBD settings to configure HW. 2913 * @param pdev 2914 * @param local_mib Not const because ETS parameters can be 2915 * changed (merge) 2916 * @param local_mib_ext 2917 * @param is_local_ets_change 2918 * @param b_can_update_ie - Update indiacate enent if indicate 2919 * event is valid and b_can_update_ie. 2920 * 2921 * @return lm_status_t 2922 */ 2923 lm_status_t 2924 lm_dcbx_set_params( 2925 IN lm_device_t *pdev, 2926 IN /*const*/ lldp_local_mib_t *local_mib, 2927 IN /*const*/ lldp_local_mib_ext_t *local_mib_ext, 2928 IN const u8_t is_local_ets_change, 2929 IN const u8_t b_can_update_ie 2930 ) 2931 { 2932 lm_status_t lm_status = LM_STATUS_SUCCESS; 2933 2934 if(!IS_PMF(pdev)) 2935 { 2936 DbgBreakMsg("lm_dcbx_update_lpme_set_params error"); 2937 return LM_STATUS_FAILURE; 2938 } 2939 2940 2941 if(FALSE == pdev->dcbx_info.is_dcbx_neg_received) 2942 { 2943 pdev->dcbx_info.is_dcbx_neg_received = TRUE; 2944 // Setting the completion bit to TRUE can be 2945 // done only once but will done on each PMF 2946 // migration because is_dcbx_neg_received is 2947 // per function. 2948 lm_dcbx_config_drv_flags(pdev, lm_dcbx_drv_flags_set_bit, DRV_FLAGS_DCB_CONFIGURED); 2949 } 2950 2951 lm_print_dcbx_drv_param(pdev, 2952 local_mib); 2953 2954 lm_get_dcbx_drv_param(pdev, 2955 local_mib, 2956 local_mib_ext); 2957 2958 MM_ACQUIRE_PHY_LOCK(pdev); 2959 lm_cmng_update(pdev); 2960 MM_RELEASE_PHY_LOCK(pdev); 2961 2962 lm_dcbx_stop_hw_tx(pdev); 2963 2964 lm_pfc_handle_pfc(pdev); 2965 2966 lm_dcbx_update_ets_params(pdev); 2967 2968 lm_dcbx_resume_hw_tx(pdev); 2969 2970 if((TRUE == pdev->dcbx_info.is_indicate_event_en) && 2971 (TRUE == b_can_update_ie)) 2972 { 2973 lm_status = lm_dcbx_ie_check_if_param_change(pdev, 2974 local_mib, 2975 local_mib_ext, 2976 is_local_ets_change); 2977 } 2978 2979 return lm_status; 2980 } 2981 /** 2982 * Read data from MCP and configure DCBX in HW and FW. 2983 * @param pdev 2984 * @param is_local_ets_change 2985 * @param b_can_update_ie Update indiacate enent if indicate 2986 * event is valid and b_can_update_ie. 2987 * 2988 * @return lm_status_t 2989 */ 2990 lm_status_t 2991 lm_dcbx_set_params_and_read_mib( 2992 IN lm_device_t *pdev, 2993 IN const u8_t is_local_ets_change, 2994 IN const u8_t b_can_update_ie 2995 ) 2996 { 2997 lldp_local_mib_t local_mib = {0}; 2998 lldp_local_mib_ext_t local_mib_ext = {0}; 2999 lm_status_t lm_status = LM_STATUS_SUCCESS; 3000 3001 // No current flow should support this. 3002 DbgBreakIf(FALSE == b_can_update_ie); 3003 3004 if(!IS_PMF(pdev)) 3005 { 3006 DbgBreakMsg("lm_dcbx_update_lpme_set_params error"); 3007 return LM_STATUS_FAILURE; 3008 } 3009 3010 lm_status = lm_dcbx_read_local_mib_fields(pdev, 3011 &local_mib, 3012 &local_mib_ext); 3013 3014 if(lm_status != LM_STATUS_SUCCESS) 3015 { 3016 3017 DbgBreakMsg("lm_dcbx_set_params: couldn't read local_mib"); 3018 return lm_status; 3019 } 3020 /******************************start Debbuging code not to submit**************************************/ 3021 mm_memcpy(&pdev->dcbx_info.local_mib_last, &local_mib, sizeof(local_mib)); 3022 /******************************end Debbuging code not to submit****************************************/ 3023 3024 lm_status = lm_dcbx_set_params(pdev, 3025 &local_mib, 3026 &local_mib_ext, 3027 is_local_ets_change, 3028 b_can_update_ie); 3029 3030 return lm_status; 3031 } 3032 /** 3033 * Disable DCBX in HW and FW. 3034 * @param pdev 3035 * @param b_can_update_ie - Update indiacate enent if indicate 3036 * event is valid and b_can_update_ie. 3037 * 3038 * @return lm_status_t 3039 */ 3040 lm_status_t 3041 lm_dcbx_disable_dcb_at_fw_and_hw( 3042 IN lm_device_t *pdev, 3043 IN const u8_t b_can_update_ie 3044 ) 3045 { 3046 lldp_local_mib_t local_mib = {0}; 3047 lldp_local_mib_ext_t local_mib_ext = {0}; 3048 lm_status_t lm_status = LM_STATUS_SUCCESS; 3049 3050 // No current flow should support this. 3051 DbgBreakIf(TRUE == b_can_update_ie); 3052 3053 if(!IS_PMF(pdev)) 3054 { 3055 DbgBreakMsg("lm_dcbx_update_lpme_set_params error"); 3056 return LM_STATUS_FAILURE; 3057 } 3058 3059 lm_status = lm_dcbx_set_params(pdev, 3060 &local_mib, 3061 &local_mib_ext, 3062 FALSE, 3063 b_can_update_ie); 3064 3065 return lm_status; 3066 } 3067 /**********************start DCBX INIT FUNCTIONS**************************************/ 3068 3069 /******************************************************************************* 3070 * Description: 3071 * 3072 * Return: 3073 ******************************************************************************/ 3074 STATIC lm_status_t 3075 lm_dcbx_init_check_params_valid(INOUT lm_device_t *pdev, 3076 OUT u32_t *buff_check, 3077 IN const u32_t buff_size) 3078 { 3079 u32_t i=0; 3080 lm_status_t ret_val = LM_STATUS_SUCCESS; 3081 3082 for (i=0 ; i < buff_size ; i++,buff_check++) 3083 { 3084 if( DCBX_CONFIG_INV_VALUE == *buff_check) 3085 { 3086 ret_val = LM_STATUS_INVALID_PARAMETER; 3087 } 3088 } 3089 return ret_val; 3090 } 3091 /******************************************************************************* 3092 * Description: Read lldp parameters. 3093 * Return: 3094 ******************************************************************************/ 3095 lm_status_t 3096 lm_dcbx_lldp_read_params(struct _lm_device_t * pdev, 3097 b10_lldp_params_get_t * lldp_params) 3098 { 3099 lldp_params_t mcp_lldp_params = {0}; 3100 lldp_dcbx_stat_t mcp_dcbx_stat = {{0}}; 3101 u32_t i = 0; 3102 u32_t *buff = NULL ; 3103 u32_t offset = 0; 3104 lm_status_t lm_status = LM_STATUS_SUCCESS; 3105 const u32_t mcp_dcbx_lldp_params_offset = OFFSETOF(shmem2_region_t,dcbx_lldp_params_offset); 3106 const u32_t mcp_dcbx_lldp_dcbx_stat_offset = OFFSETOF(shmem2_region_t,dcbx_lldp_dcbx_stat_offset); 3107 3108 mm_mem_zero(lldp_params, sizeof(b10_lldp_params_get_t)); 3109 3110 3111 offset = SHMEM_LLDP_DCBX_PARAMS_NONE; 3112 3113 lm_dcbx_read_shmem2_mcp_fields(pdev, 3114 mcp_dcbx_lldp_params_offset, 3115 &offset); 3116 3117 if((!IS_DCB_ENABLED(pdev)) || 3118 (SHMEM_LLDP_DCBX_PARAMS_NONE == offset)) 3119 {//DCBX isn't supported on E1 3120 return LM_STATUS_FAILURE; 3121 } 3122 3123 lldp_params->config_lldp_params.overwrite_settings = 3124 pdev->params.lldp_config_params.overwrite_settings; 3125 3126 if (SHMEM_LLDP_DCBX_PARAMS_NONE != offset) 3127 { 3128 offset += PORT_ID(pdev) * sizeof(lldp_params_t); 3129 3130 //Read the data first 3131 buff = (u32_t *)&mcp_lldp_params; 3132 for(i=0 ;i<sizeof(lldp_params_t); i+=4,buff++) 3133 { 3134 *buff = REG_RD(pdev, 3135 (offset + i)); 3136 } 3137 lldp_params->ver_num = LLDP_PARAMS_VER_NUM; 3138 lldp_params->config_lldp_params.msg_tx_hold = mcp_lldp_params.msg_tx_hold; 3139 lldp_params->config_lldp_params.msg_fast_tx = mcp_lldp_params.msg_fast_tx_interval; 3140 lldp_params->config_lldp_params.tx_credit_max = mcp_lldp_params.tx_crd_max; 3141 lldp_params->config_lldp_params.msg_tx_interval = mcp_lldp_params.msg_tx_interval; 3142 lldp_params->config_lldp_params.tx_fast = mcp_lldp_params.tx_fast; 3143 3144 3145 // Preparation for new shmem 3146 ASSERT_STATIC(ARRSIZE(lldp_params->remote_chassis_id) >= ARRSIZE(mcp_lldp_params.peer_chassis_id)); 3147 ASSERT_STATIC(sizeof(lldp_params->remote_chassis_id[0]) == sizeof(mcp_lldp_params.peer_chassis_id[0])); 3148 for(i=0 ; i< ARRSIZE(mcp_lldp_params.peer_chassis_id) ; i++) 3149 { 3150 lldp_params->remote_chassis_id[i] = mcp_lldp_params.peer_chassis_id[i]; 3151 } 3152 3153 ASSERT_STATIC(sizeof(lldp_params->remote_port_id[0]) == sizeof(mcp_lldp_params.peer_port_id[0])); 3154 ASSERT_STATIC(ARRSIZE(lldp_params->remote_port_id) > ARRSIZE(mcp_lldp_params.peer_port_id)); 3155 for(i=0 ; i<ARRSIZE(mcp_lldp_params.peer_port_id) ; i++) 3156 { 3157 lldp_params->remote_port_id[i] = mcp_lldp_params.peer_port_id[i]; 3158 } 3159 3160 lldp_params->admin_status = mcp_lldp_params.admin_status; 3161 } 3162 else 3163 {// DCBX not supported in MCP 3164 DbgBreakMsg("DCBX DCBX params supported"); 3165 lm_status= LM_STATUS_FAILURE; 3166 } 3167 3168 offset = SHMEM_LLDP_DCBX_STAT_NONE; 3169 3170 lm_dcbx_read_shmem2_mcp_fields(pdev, 3171 mcp_dcbx_lldp_dcbx_stat_offset, 3172 &offset); 3173 3174 if (SHMEM_LLDP_DCBX_STAT_NONE != offset) 3175 { 3176 offset += PORT_ID(pdev) * sizeof(mcp_dcbx_stat); 3177 3178 //Read the data first 3179 buff = (u32_t *)&mcp_dcbx_stat; 3180 for(i=0 ;i<sizeof(mcp_dcbx_stat); i+=4,buff++) 3181 { 3182 *buff = REG_RD(pdev, 3183 (offset + i)); 3184 } 3185 // Preparation for new shmem 3186 3187 ASSERT_STATIC(ARRSIZE(lldp_params->local_chassis_id) >= ARRSIZE(mcp_dcbx_stat.local_chassis_id)); 3188 ASSERT_STATIC(sizeof(lldp_params->local_chassis_id[0]) >= sizeof(mcp_dcbx_stat.local_chassis_id[0])); 3189 for(i=0 ; i< ARRSIZE(mcp_dcbx_stat.local_chassis_id) ; i++) 3190 { 3191 lldp_params->local_chassis_id[i] = mcp_dcbx_stat.local_chassis_id[i]; 3192 } 3193 3194 ASSERT_STATIC(ARRSIZE(lldp_params->local_port_id) >= ARRSIZE(mcp_dcbx_stat.local_port_id)); 3195 ASSERT_STATIC(sizeof(lldp_params->local_port_id[0]) >= sizeof(mcp_dcbx_stat.local_port_id[0])); 3196 for(i=0 ; i< ARRSIZE(mcp_dcbx_stat.local_port_id) ; i++) 3197 { 3198 lldp_params->local_port_id[i] = mcp_dcbx_stat.local_port_id[i]; 3199 } 3200 } 3201 else 3202 {// DCBX not supported in MCP 3203 DbgBreakMsg("DCBX DCBX stats supported"); 3204 lm_status= LM_STATUS_FAILURE; 3205 } 3206 3207 return lm_status; 3208 } 3209 /******************************************************************************* 3210 * Description: 3211 * mcp_pg_bw_tbl_size: In elements. 3212 * set_configuration_bw_size: In elements. 3213 * Return: 3214 ******************************************************************************/ 3215 STATIC void 3216 lm_dcbx_get_bw_percentage_tbl(struct _lm_device_t * pdev, 3217 OUT u32_t * set_configuration_bw, 3218 IN u32_t * mcp_pg_bw_tbl, 3219 IN const u8_t set_configuration_bw_size, 3220 IN const u8_t mcp_pg_bw_tbl_size) 3221 { 3222 3223 u8_t i = 0; 3224 const u8_t mcp_pg_bw_tbl_size_in_bytes = (sizeof(*mcp_pg_bw_tbl)*(mcp_pg_bw_tbl_size)); 3225 3226 DbgBreakIf(set_configuration_bw_size != mcp_pg_bw_tbl_size); 3227 3228 DbgBreakIf(0 != (mcp_pg_bw_tbl_size_in_bytes % sizeof(u32_t))); 3229 for(i=0 ;i<set_configuration_bw_size ;i++) 3230 { 3231 set_configuration_bw[i] = DCBX_PG_BW_GET(mcp_pg_bw_tbl,i); 3232 } 3233 } 3234 /******************************************************************************* 3235 * Description: Parse ets_pri_pg data and spread it from nibble to 32 bits. 3236 * 3237 * Return: 3238 ******************************************************************************/ 3239 STATIC void 3240 lm_dcbx_get_ets_pri_pg_tbl(struct _lm_device_t * pdev, 3241 OUT u32_t * set_configuration_ets_pg, 3242 IN const u32_t * mcp_pri_pg_tbl, 3243 IN const u8_t set_priority_app_size, 3244 IN const u8_t mcp_pri_pg_tbl_size) 3245 { 3246 u8_t i = 0; 3247 const u8_t mcp_pri_pg_tbl_size_in_bytes = (sizeof(*mcp_pri_pg_tbl)*(mcp_pri_pg_tbl_size)); 3248 3249 DbgBreakIf(set_priority_app_size != (mcp_pri_pg_tbl_size)); 3250 3251 // Arrays that there cell are less than 32 bit are still 3252 // in big endian mode. 3253 DbgBreakIf(0 != (mcp_pri_pg_tbl_size_in_bytes % sizeof(u32_t))); 3254 3255 // Nibble handling 3256 for(i=0 ; i < set_priority_app_size ; i++) 3257 { 3258 set_configuration_ets_pg[i] = DCBX_PRI_PG_GET(mcp_pri_pg_tbl,i); 3259 } 3260 } 3261 /******************************************************************************* 3262 * Description: Parse priority app data. 3263 * 3264 * Return: 3265 ******************************************************************************/ 3266 STATIC void 3267 lm_dcbx_get_priority_app_table(struct _lm_device_t * pdev, 3268 OUT struct _admin_priority_app_table_t * set_priority_app, 3269 IN dcbx_app_priority_entry_t * mcp_array, 3270 IN const u8_t set_priority_app_size, 3271 IN const u8_t mcp_array_size) 3272 { 3273 u8_t i = 0; 3274 3275 if(set_priority_app_size > mcp_array_size) 3276 { 3277 DbgBreakIf(1); 3278 return; 3279 } 3280 3281 for(i=0 ;i<set_priority_app_size ;i++) 3282 { 3283 if(GET_FLAGS(mcp_array[i].appBitfield,DCBX_APP_ENTRY_VALID)) 3284 { 3285 set_priority_app[i].valid = TRUE; 3286 } 3287 3288 if(GET_FLAGS(mcp_array[i].appBitfield,DCBX_APP_SF_ETH_TYPE)) 3289 { 3290 set_priority_app[i].traffic_type = TRAFFIC_TYPE_ETH; 3291 } 3292 else 3293 { 3294 set_priority_app[i].traffic_type = TRAFFIC_TYPE_PORT; 3295 } 3296 set_priority_app[i].priority = mcp_array[i].pri_bitmap; 3297 3298 3299 // This has no logic this is only done for supporting old bootcodes. 3300 // The boot code still expexts u8 [2] instead of u16 3301 set_priority_app[i].app_id = mcp_array[i].app_id; 3302 } 3303 3304 } 3305 /** 3306 * @description 3307 * Fill the operational parameters. 3308 * @param pdev 3309 * @param dcbx_params 3310 * 3311 * @return STATIC void 3312 */ 3313 STATIC void 3314 lm_dcbx_read_params_fill_oper_state(struct _lm_device_t * pdev, 3315 b10_dcbx_params_get_t * dcbx_params) 3316 { 3317 lm_dcbx_indicate_event_t *indicate_event = &pdev->dcbx_info.indicate_event; 3318 3319 if(TRUE == pdev->params.dcbx_port_params.app.enabled) 3320 { 3321 SET_FLAGS(dcbx_params->dcb_current_oper_state_bitmap,PRIORITY_TAGGING_IS_CURRENTLY_OPERATIONAL); 3322 } 3323 3324 if(TRUE == pdev->params.dcbx_port_params.pfc.enabled) 3325 { 3326 SET_FLAGS(dcbx_params->dcb_current_oper_state_bitmap,PFC_IS_CURRENTLY_OPERATIONAL); 3327 } 3328 3329 if(TRUE == pdev->params.dcbx_port_params.ets.enabled) 3330 { 3331 SET_FLAGS(dcbx_params->dcb_current_oper_state_bitmap,ETS_IS_CURRENTLY_OPERATIONAL); 3332 } 3333 3334 if(GET_FLAGS(indicate_event->dcb_current_oper_state_bitmap, 3335 DCB_STATE_CONFIGURED_BY_OS_QOS)) 3336 { 3337 SET_FLAGS(dcbx_params->dcb_current_oper_state_bitmap, 3338 DRIVER_CONFIGURED_BY_OS_QOS); 3339 } 3340 3341 if(GET_FLAGS(indicate_event->dcb_current_oper_state_bitmap, 3342 DCB_STATE_CONFIGURED_BY_OS_QOS_TO_WILLING)) 3343 { 3344 SET_FLAGS(dcbx_params->dcb_current_oper_state_bitmap, 3345 DRIVER_CONFIGURED_BY_OS_QOS_TO_WILLING); 3346 } 3347 } 3348 /******************************************************************************* 3349 * Description: Read DCBX parameters from admin/local and remote MIBs. 3350 * 3351 * Return: 3352 * LM_STATUS_FAILURE - All/Some of the parameters could not be read. 3353 * LM_STATUS_SUCCESS - All the MIBs where read successfully. 3354 ******************************************************************************/ 3355 lm_status_t 3356 lm_dcbx_read_params(struct _lm_device_t * pdev, 3357 b10_dcbx_params_get_t * dcbx_params) 3358 { 3359 lldp_admin_mib_t admin_mib = {0}; 3360 lldp_local_mib_t local_mib = {0}; 3361 lldp_remote_mib_t remote_mib = {0}; 3362 lldp_dcbx_stat_t mcp_dcbx_stat = {{0}}; 3363 lm_dcbx_stat dcbx_stat = {0}; 3364 u32_t pfc_frames_sent[2] = {0}; 3365 u32_t pfc_frames_received[2] = {0}; 3366 u32_t i = 0; 3367 u32_t *buff = NULL; 3368 u32_t offset = SHMEM_LLDP_DCBX_PARAMS_NONE; 3369 lm_status_t lm_status = LM_STATUS_SUCCESS; 3370 const u32_t mcp_dcbx_lldp_params_offset = OFFSETOF(shmem2_region_t,dcbx_lldp_params_offset); 3371 const u32_t mcp_dcbx_lldp_dcbx_stat_offset = OFFSETOF(shmem2_region_t,dcbx_lldp_dcbx_stat_offset); 3372 3373 mm_mem_zero(dcbx_params, sizeof(b10_dcbx_params_get_t)); 3374 3375 lm_dcbx_read_params_fill_oper_state(pdev,dcbx_params); 3376 3377 lm_dcbx_read_shmem2_mcp_fields(pdev, 3378 mcp_dcbx_lldp_params_offset, 3379 &offset); 3380 3381 if((!IS_DCB_ENABLED(pdev)) || 3382 (SHMEM_LLDP_DCBX_PARAMS_NONE == offset)) 3383 {//DCBX isn't supported on E1 3384 return LM_STATUS_FAILURE; 3385 } 3386 3387 dcbx_params->config_dcbx_params.overwrite_settings = 3388 pdev->params.dcbx_config_params.overwrite_settings; 3389 3390 // E3.0 might be 4...not supported in current shmem 3391 ASSERT_STATIC( 2 == PORT_MAX ); 3392 3393 if (SHMEM_LLDP_DCBX_PARAMS_NONE != offset) 3394 { 3395 offset = LM_DCBX_ADMIN_MIB_OFFSET(pdev ,offset); 3396 3397 //Read the data first 3398 buff = (u32_t *)&admin_mib; 3399 for(i=0 ;i<sizeof(lldp_admin_mib_t); i+=4,buff++) 3400 { 3401 *buff = REG_RD(pdev, 3402 (offset + i)); 3403 } 3404 3405 dcbx_params->config_dcbx_params.dcb_enable = IS_DCB_ENABLED(pdev) ; 3406 3407 if(GET_FLAGS(admin_mib.ver_cfg_flags,DCBX_DCBX_ENABLED)) 3408 { 3409 dcbx_params->config_dcbx_params.admin_dcbx_enable = 1 ; 3410 } 3411 3412 if(GET_FLAGS(admin_mib.ver_cfg_flags,DCBX_VERSION_CEE)) 3413 { 3414 dcbx_params->config_dcbx_params.admin_dcbx_version = ADMIN_DCBX_VERSION_CEE; 3415 } 3416 else if(GET_FLAGS(admin_mib.ver_cfg_flags,DCBX_VERSION_IEEE)) 3417 { 3418 dcbx_params->config_dcbx_params.admin_dcbx_version = ADMIN_DCBX_VERSION_IEEE; 3419 } 3420 else 3421 { 3422 dcbx_params->config_dcbx_params.admin_dcbx_version = OVERWRITE_SETTINGS_INVALID; 3423 DbgMessage(pdev, WARN, " unknown DCBX version "); 3424 } 3425 3426 dcbx_params->config_dcbx_params.admin_ets_enable = admin_mib.features.ets.enabled; 3427 3428 dcbx_params->config_dcbx_params.admin_pfc_enable = admin_mib.features.pfc.enabled; 3429 3430 //FOR IEEE pdev->params.dcbx_config_params.admin_tc_supported_tx_enable 3431 if(GET_FLAGS(admin_mib.ver_cfg_flags,DCBX_ETS_CONFIG_TX_ENABLED)) 3432 { 3433 dcbx_params->config_dcbx_params.admin_ets_configuration_tx_enable = TRUE; 3434 } 3435 //For IEEE admin_ets_recommendation_tx_enable 3436 3437 if(GET_FLAGS(admin_mib.ver_cfg_flags,DCBX_PFC_CONFIG_TX_ENABLED)) 3438 { 3439 dcbx_params->config_dcbx_params.admin_pfc_tx_enable = TRUE; 3440 } 3441 3442 if(GET_FLAGS(admin_mib.ver_cfg_flags,DCBX_APP_CONFIG_TX_ENABLED)) 3443 { 3444 dcbx_params->config_dcbx_params.admin_application_priority_tx_enable = TRUE; 3445 } 3446 3447 3448 if(GET_FLAGS(admin_mib.ver_cfg_flags,DCBX_ETS_WILLING)) 3449 { 3450 dcbx_params->config_dcbx_params.admin_ets_willing = TRUE; 3451 } 3452 3453 //For IEEE admin_ets_reco_valid 3454 3455 if(GET_FLAGS(admin_mib.ver_cfg_flags,DCBX_PFC_WILLING)) 3456 { 3457 dcbx_params->config_dcbx_params.admin_pfc_willing = TRUE; 3458 } 3459 3460 3461 if(GET_FLAGS(admin_mib.ver_cfg_flags,DCBX_APP_WILLING)) 3462 { 3463 dcbx_params->config_dcbx_params.admin_app_priority_willing = TRUE; 3464 } 3465 3466 3467 lm_dcbx_get_bw_percentage_tbl(pdev, 3468 dcbx_params->config_dcbx_params.admin_configuration_bw_percentage, 3469 admin_mib.features.ets.pg_bw_tbl, 3470 ARRSIZE(dcbx_params->config_dcbx_params.admin_configuration_bw_percentage), 3471 DCBX_MAX_NUM_PG_BW_ENTRIES); 3472 3473 lm_dcbx_get_ets_pri_pg_tbl(pdev, 3474 dcbx_params->config_dcbx_params.admin_configuration_ets_pg, 3475 admin_mib.features.ets.pri_pg_tbl, 3476 ARRSIZE(dcbx_params->config_dcbx_params.admin_configuration_ets_pg), 3477 DCBX_MAX_NUM_PRI_PG_ENTRIES); 3478 3479 3480 //For IEEE admin_recommendation_bw_percentage 3481 //For IEEE admin_recommendation_ets_pg 3482 dcbx_params->config_dcbx_params.admin_pfc_bitmap = admin_mib.features.pfc.pri_en_bitmap; 3483 3484 lm_dcbx_get_priority_app_table(pdev, 3485 dcbx_params->config_dcbx_params.admin_priority_app_table, 3486 admin_mib.features.app.app_pri_tbl, 3487 ARRSIZE(dcbx_params->config_dcbx_params.admin_priority_app_table), 3488 ARRSIZE(admin_mib.features.app.app_pri_tbl)); 3489 3490 dcbx_params->config_dcbx_params.admin_default_priority = admin_mib.features.app.default_pri; 3491 } 3492 else 3493 {// DCBX not supported in MCP 3494 DbgBreakMsg("DCBX DCBX params not supported"); 3495 lm_status= LM_STATUS_FAILURE; 3496 } 3497 3498 lm_status = lm_dcbx_read_remote_local_mib(pdev, 3499 (u32_t *)&local_mib, 3500 DCBX_READ_LOCAL_MIB); 3501 3502 if (LM_STATUS_SUCCESS == lm_status) 3503 { 3504 3505 if(0 == GET_FLAGS(local_mib.error,DCBX_REMOTE_MIB_ERROR)) 3506 { 3507 SET_FLAGS(dcbx_params->dcb_current_oper_state_bitmap,DCBX_CURRENT_STATE_IS_SYNC); 3508 } 3509 3510 dcbx_params->ver_num = DCBX_PARAMS_VER_NUM; 3511 dcbx_params->local_tc_supported = local_mib.features.app.tc_supported; 3512 dcbx_params->local_pfc_caps = local_mib.features.pfc.pfc_caps; 3513 dcbx_params->local_ets_enable = local_mib.features.ets.enabled; 3514 dcbx_params->local_pfc_enable = local_mib.features.pfc.enabled; 3515 3516 lm_dcbx_get_bw_percentage_tbl(pdev, 3517 dcbx_params->local_configuration_bw_percentage, 3518 local_mib.features.ets.pg_bw_tbl, 3519 ARRSIZE(dcbx_params->local_configuration_bw_percentage), 3520 DCBX_MAX_NUM_PG_BW_ENTRIES); 3521 3522 lm_dcbx_get_ets_pri_pg_tbl(pdev, 3523 dcbx_params->local_configuration_ets_pg, 3524 local_mib.features.ets.pri_pg_tbl, 3525 ARRSIZE(dcbx_params->local_configuration_ets_pg), 3526 DCBX_MAX_NUM_PRI_PG_ENTRIES); 3527 3528 dcbx_params->local_pfc_bitmap = local_mib.features.pfc.pri_en_bitmap; 3529 3530 lm_dcbx_get_priority_app_table(pdev, 3531 dcbx_params->local_priority_app_table, 3532 local_mib.features.app.app_pri_tbl, 3533 ARRSIZE(dcbx_params->local_priority_app_table), 3534 ARRSIZE(local_mib.features.app.app_pri_tbl)); 3535 3536 if(GET_FLAGS(local_mib.error,DCBX_LOCAL_PFC_MISMATCH)) 3537 { 3538 dcbx_params->pfc_mismatch = TRUE; 3539 } 3540 3541 if(GET_FLAGS(local_mib.error,DCBX_LOCAL_APP_MISMATCH)) 3542 { 3543 dcbx_params->priority_app_mismatch = TRUE; 3544 } 3545 } 3546 else 3547 {// DCBX not supported in MCP 3548 DbgBreakMsg("DCBX Negotiation result not supported"); 3549 lm_status= LM_STATUS_FAILURE; 3550 } 3551 // Get remote MIB data 3552 3553 lm_status = lm_dcbx_read_remote_local_mib(pdev, 3554 (u32_t *)&remote_mib, 3555 DCBX_READ_REMOTE_MIB); 3556 if (LM_STATUS_SUCCESS == lm_status) 3557 { 3558 3559 dcbx_params->remote_tc_supported = remote_mib.features.app.tc_supported; 3560 dcbx_params->remote_pfc_cap = remote_mib.features.pfc.pfc_caps; 3561 if(GET_FLAGS(remote_mib.flags,DCBX_REMOTE_ETS_RECO_VALID)) 3562 { 3563 dcbx_params->remote_ets_reco_valid = TRUE; 3564 } 3565 3566 if(GET_FLAGS(remote_mib.flags,DCBX_ETS_REM_WILLING)) 3567 { 3568 dcbx_params->remote_ets_willing = TRUE; 3569 } 3570 3571 if(GET_FLAGS(remote_mib.flags,DCBX_PFC_REM_WILLING)) 3572 { 3573 dcbx_params->remote_pfc_willing = TRUE; 3574 } 3575 3576 if(GET_FLAGS(remote_mib.flags,DCBX_APP_REM_WILLING)) 3577 { 3578 dcbx_params->remote_app_priority_willing = TRUE; 3579 } 3580 3581 lm_dcbx_get_bw_percentage_tbl(pdev, 3582 dcbx_params->remote_configuration_bw_percentage, 3583 remote_mib.features.ets.pg_bw_tbl, 3584 ARRSIZE(dcbx_params->remote_configuration_bw_percentage), 3585 DCBX_MAX_NUM_PG_BW_ENTRIES); 3586 3587 lm_dcbx_get_ets_pri_pg_tbl(pdev, 3588 dcbx_params->remote_configuration_ets_pg, 3589 remote_mib.features.ets.pri_pg_tbl, 3590 ARRSIZE(dcbx_params->remote_configuration_ets_pg), 3591 DCBX_MAX_NUM_PRI_PG_ENTRIES); 3592 // For IEEE remote_recommendation_bw_percentage 3593 // For IEEE remote_recommendation_ets_pg 3594 3595 dcbx_params->remote_pfc_bitmap = remote_mib.features.pfc.pri_en_bitmap; 3596 3597 lm_dcbx_get_priority_app_table(pdev, 3598 dcbx_params->remote_priority_app_table, 3599 remote_mib.features.app.app_pri_tbl, 3600 ARRSIZE(dcbx_params->remote_priority_app_table), 3601 ARRSIZE(remote_mib.features.app.app_pri_tbl)); 3602 } 3603 else 3604 {// DCBX not supported in MCP 3605 DbgBreakMsg("DCBX remote MIB not supported"); 3606 lm_status= LM_STATUS_FAILURE; 3607 } 3608 3609 // Get negotiation results MIB data 3610 offset = SHMEM_LLDP_DCBX_STAT_NONE; 3611 3612 lm_dcbx_read_shmem2_mcp_fields(pdev, 3613 mcp_dcbx_lldp_dcbx_stat_offset, 3614 &offset); 3615 3616 // E3.0 might be 4...not supported in current shmem 3617 ASSERT_STATIC( 2 == PORT_MAX ); 3618 3619 if (SHMEM_LLDP_DCBX_STAT_NONE != offset) 3620 { 3621 offset += PORT_ID(pdev) * sizeof(mcp_dcbx_stat); 3622 3623 //Read the data first 3624 buff = (u32_t *)&mcp_dcbx_stat; 3625 for(i=0 ;i<sizeof(mcp_dcbx_stat); i+=4,buff++) 3626 { 3627 *buff = REG_RD(pdev, 3628 (offset + i)); 3629 } 3630 3631 dcbx_params->dcbx_frames_sent = mcp_dcbx_stat.num_tx_dcbx_pkts; 3632 dcbx_params->dcbx_frames_received = mcp_dcbx_stat.num_rx_dcbx_pkts; 3633 } 3634 else 3635 {// DCBX not supported in MCP 3636 DbgBreakMsg("DCBX statistic not supported"); 3637 lm_status= LM_STATUS_FAILURE; 3638 } 3639 // TODO - Move to lm_stat 3640 3641 3642 if(pdev->vars.mac_type == MAC_TYPE_EMAC) 3643 { 3644 MM_ACQUIRE_PHY_LOCK(pdev); 3645 // EMAC stats are not collected through statitic code. 3646 elink_pfc_statistic(&pdev->params.link, &pdev->vars.link, 3647 pfc_frames_sent, pfc_frames_received); 3648 3649 MM_RELEASE_PHY_LOCK(pdev); 3650 3651 dcbx_stat.pfc_frames_sent = ((u64_t)(pfc_frames_sent[1]) << 32) + pfc_frames_sent[0]; 3652 3653 dcbx_stat.pfc_frames_received = ((u64_t)(pfc_frames_received[1]) << 32) + pfc_frames_received[0]; 3654 } 3655 else 3656 { 3657 lm_stats_get_dcb_stats( pdev, &dcbx_stat ); 3658 3659 } 3660 3661 dcbx_params->pfc_frames_sent = dcbx_stat.pfc_frames_sent; 3662 3663 dcbx_params->pfc_frames_received = dcbx_stat.pfc_frames_received; 3664 3665 return lm_status; 3666 } 3667 /******************************************************************************* 3668 * Description: 3669 * 3670 * Return: 3671 ******************************************************************************/ 3672 void 3673 lm_dcbx_init_lpme_set_params(struct _lm_device_t *pdev) 3674 { 3675 lm_status_t lm_status = LM_STATUS_SUCCESS; 3676 3677 if( TRUE == pdev->dcbx_info.is_dcbx_neg_received) 3678 { 3679 // DCBX negotiation ended normaly. 3680 return; 3681 } 3682 //DbgBreakMsg(" lm_dcbx_init_lpme_set_params : DCBX timer configuration \n"); 3683 //DbgMessage(pdev, FATAL, "lm_dcbx_init_lpme_set_params : DCBX timer configuration \n"); 3684 // DCBX negotiation didn�t ended normaly yet. 3685 // No lock is needed to be taken because lm_dcbx_set_params is only called from a WI 3686 lm_status = lm_dcbx_set_params_and_read_mib(pdev, 3687 FALSE, 3688 TRUE); 3689 3690 DbgBreakIf(LM_STATUS_SUCCESS != lm_status); 3691 } 3692 /** 3693 * look for an entry that isn't iSCSI or FCoE and return it's 3694 * position. 3695 * @param pdev 3696 * @param app 3697 * 3698 * @return STATIC u8_t 3699 */ 3700 STATIC u8_t 3701 lm_dcbx_app_find_non_off_tt_entry( 3702 IN lm_device_t *pdev, 3703 INOUT dcbx_app_priority_feature_t *app 3704 ) 3705 { 3706 dcbx_app_priority_entry_t *app_priority_entry = NULL; 3707 u8_t entry = 0; 3708 3709 for(entry = 0; entry < ARRSIZE(app->app_pri_tbl); entry++) 3710 { 3711 app_priority_entry = &(app->app_pri_tbl[entry]); 3712 3713 if(lm_dcbx_cee_is_entry_fcoe_classif(app_priority_entry->appBitfield, 3714 app_priority_entry->app_id)) 3715 { 3716 DbgMessage(pdev, INFORM, "lm_dcbx_app_find_non_off_tt_entry :FCOE entry"); 3717 } 3718 else if(lm_dcbx_cee_is_entry_iscsi_classif(app_priority_entry->appBitfield, 3719 app_priority_entry->app_id)) 3720 { 3721 DbgMessage(pdev, INFORM, "lm_dcbx_app_find_non_off_tt_entry :ISCSI entry"); 3722 } 3723 else 3724 { 3725 // Found an entry that isn't ISCSI or FCOE 3726 break; 3727 } 3728 } 3729 3730 return entry; 3731 } 3732 /** 3733 * @description 3734 * 3735 * @param pdev 3736 * @param app 3737 * @param other_traf_type_entry - For entries that are not 3738 * predefined 3739 * @param app_id 3740 * @param traffic_type 3741 * @param priority 3742 * 3743 * @return STATIC lm_status_t 3744 */ 3745 STATIC lm_status_t 3746 lm_dcbx_admin_mib_update_app_pri( 3747 IN lm_device_t *pdev, 3748 INOUT dcbx_app_priority_feature_t *app, 3749 INOUT u8_t *next_free_app_id_entry, 3750 IN const u16_t app_id, 3751 IN const u8_t traffic_type, 3752 IN const u8_t priority) 3753 { 3754 lm_status_t lm_status = LM_STATUS_SUCCESS; 3755 u8_t traf_type_entry = 0; 3756 u8_t app_bit_field = DCBX_APP_ENTRY_VALID; 3757 3758 switch(traffic_type) 3759 { 3760 case TRAFFIC_TYPE_ETH: 3761 app_bit_field |= DCBX_APP_SF_ETH_TYPE; 3762 break; 3763 case TRAFFIC_TYPE_PORT: 3764 app_bit_field |= DCBX_APP_SF_PORT; 3765 break; 3766 default: 3767 DbgBreakMsg("lm_dcbx_admin_mib_update_app_pri illegal traffic_type entry "); 3768 return LM_STATUS_INVALID_PARAMETER; 3769 } 3770 3771 if(ARRSIZE(app->app_pri_tbl) <= (*next_free_app_id_entry) ) 3772 { 3773 // Reserve two entries to iSCSI and FCoE (in case they will 3774 // be received after the 16th application priority entry). 3775 if(lm_dcbx_cee_is_entry_iscsi_classif( 3776 app_bit_field, 3777 app_id ) || 3778 lm_dcbx_cee_is_entry_fcoe_classif( 3779 app_bit_field, 3780 app_id)) 3781 { 3782 traf_type_entry = lm_dcbx_app_find_non_off_tt_entry(pdev, app); 3783 3784 if (ARRSIZE(app->app_pri_tbl) <= traf_type_entry) 3785 { 3786 DbgBreakMsg("lm_dcbx_admin_mib_update_app_pri : traf_type_entry contains an invalid value "); 3787 return lm_status; 3788 } 3789 } 3790 else 3791 { 3792 return lm_status; 3793 } 3794 } 3795 else 3796 { 3797 DbgBreakIf(ARRSIZE(app->app_pri_tbl) <= (*next_free_app_id_entry)); 3798 traf_type_entry = (*next_free_app_id_entry)++; 3799 } 3800 3801 DbgBreakIf(ARRSIZE(app->app_pri_tbl) <= traf_type_entry ); 3802 3803 app->app_pri_tbl[traf_type_entry].app_id = app_id; 3804 3805 app->app_pri_tbl[traf_type_entry].pri_bitmap =(u8_t)(1 << priority); 3806 3807 app->app_pri_tbl[traf_type_entry].appBitfield = app_bit_field; 3808 3809 return lm_status; 3810 } 3811 /** 3812 * @description 3813 * Update admin MIB classification entries with OS DCBX 3814 * classification configuration. 3815 * @param pdev 3816 * @param admin_mib 3817 * @param dcb_params 3818 * @param classif_local_vars 3819 * 3820 * @return STATIC lm_status_t 3821 */ 3822 STATIC lm_status_t 3823 lm_dcbx_ie_admin_mib_classif(IN lm_device_t *pdev, 3824 INOUT dcbx_app_priority_feature_t *app, 3825 IN const dcb_classif_params_t *classif_params, 3826 IN const u32_t flags 3827 ) 3828 { 3829 lm_dcbx_indicate_event_t *indicate_event = &pdev->dcbx_info.indicate_event; 3830 dcb_classif_elem_t *p_classif_elem = (dcb_classif_elem_t *)classif_params->classif_table; 3831 u32_t i = 0; 3832 u8_t traffic_type = 0; 3833 u8_t b_update_admin = FALSE; 3834 // Other traffic type is defined as not ISCSI or FCOE 3835 u8_t next_free_app_id_entry = 0; 3836 3837 mm_mem_zero(&(app->app_pri_tbl), sizeof(app->app_pri_tbl)); 3838 app->default_pri = 0; 3839 app->tc_supported = 0; 3840 indicate_event->iscsi_tcp_pri = LM_DCBX_ILLEGAL_PRI; 3841 3842 if(0 == GET_FLAGS(flags, DCB_PARAMS_CLASSIF_ENABLED)) 3843 { 3844 return LM_STATUS_SUCCESS; 3845 } 3846 3847 for(i = 0; i < classif_params->num_classif_elements; i++ , p_classif_elem++) 3848 { 3849 b_update_admin = FALSE; 3850 3851 if(DCB_ACTION_PRIORITY != p_classif_elem->action_selector) 3852 { 3853 // VBD only supports condition_selector that is based on priority 3854 continue; 3855 } 3856 switch(p_classif_elem->condition_selector) 3857 { 3858 case DCB_CONDITION_DEFAULT: 3859 // If default entry exist it must be the first entry ISCSI and FCOE priority 3860 // will be update accordingly. If OS gave us an ISCSI or FCOE entry it will 3861 // overwrite this value. 3862 DbgBreakIf(0 != i); 3863 app->default_pri = (u8_t)p_classif_elem->action_field; 3864 break; 3865 3866 case DCB_CONDITION_TCP_OR_UDP_PORT: 3867 traffic_type = TRAFFIC_TYPE_PORT; 3868 b_update_admin = TRUE; 3869 break; 3870 3871 case DCB_CONDITION_ETHERTYPE: 3872 traffic_type = TRAFFIC_TYPE_ETH; 3873 b_update_admin = TRUE; 3874 break; 3875 case DCB_CONDITION_TCP_PORT: 3876 if(TCP_PORT_ISCSI == p_classif_elem->condition_field) 3877 { 3878 // Check if ISCSI prioriy changed from last time. 3879 if(LM_DCBX_ILLEGAL_PRI <= p_classif_elem->action_field ) 3880 { 3881 DbgBreakMsg("lm_dcbx_ie_admin_mib_update_runtime_classif illegal action field"); 3882 return LM_STATUS_FAILURE; 3883 } 3884 if(p_classif_elem->action_field != 3885 indicate_event->iscsi_tcp_pri) 3886 { 3887 indicate_event->iscsi_tcp_pri = p_classif_elem->action_field; 3888 } 3889 } 3890 break; 3891 case DCB_CONDITION_RESERVED: 3892 case DCB_CONDITION_UDP_PORT://Fall through 3893 case DCB_CONDITION_NETDIRECT_PORT://Fall through 3894 //Not supported by VBD 3895 break; 3896 default: 3897 DbgBreakMsg("lm_dcbx_runtime_params_updated_en_classif_entries: illegal entry "); 3898 break; 3899 } 3900 if(TRUE == b_update_admin) 3901 { 3902 lm_dcbx_admin_mib_update_app_pri(pdev, 3903 app, 3904 &next_free_app_id_entry, 3905 p_classif_elem->condition_field, 3906 traffic_type, 3907 (u8_t)p_classif_elem->action_field); 3908 } 3909 } 3910 3911 app->tc_supported = next_free_app_id_entry; 3912 3913 return LM_STATUS_SUCCESS; 3914 } 3915 /** 3916 * This function is for wrapper for the function 3917 * lm_dcbx_ie_admin_mib_classif and it purpose is for telling if 3918 * DCBX configuration needs to change but MCP was not update. 3919 * @param pdev 3920 * @param app 3921 * @param classif_params 3922 * @param classif_change_mcp_not_aware 3923 * @param flags 3924 * 3925 * @return STATIC lm_device_t 3926 */ 3927 STATIC lm_status_t 3928 lm_dcbx_ie_admin_mib_classif_wrapper(IN lm_device_t *pdev, 3929 INOUT dcbx_app_priority_feature_t *app, 3930 IN const dcb_classif_params_t *classif_params, 3931 OUT u8_t *classif_change_mcp_not_aware, 3932 IN const u32_t flags 3933 ) 3934 { 3935 lm_dcbx_indicate_event_t *indicate_event = &pdev->dcbx_info.indicate_event; 3936 lm_status_t lm_status = LM_STATUS_SUCCESS; 3937 const u16_t iscsi_tcp_pri_prev = indicate_event->iscsi_tcp_pri; 3938 3939 lm_status = lm_dcbx_ie_admin_mib_classif(pdev,app,classif_params,flags); 3940 3941 if(iscsi_tcp_pri_prev != indicate_event->iscsi_tcp_pri) 3942 { 3943 (*classif_change_mcp_not_aware) = TRUE; 3944 } 3945 3946 return lm_status; 3947 } 3948 3949 /** 3950 * @description 3951 * Update admin MIB ETS parameters. 3952 * @param pdev 3953 * @param admin_ets 3954 * @param bw_tbl 3955 * @param pri_pg 3956 * @param bw_tbl_size 3957 * @param pri_pg_size 3958 */ 3959 void 3960 lm_dcbx_admin_mib_update_ets_param( 3961 IN lm_device_t *pdev, 3962 IN dcbx_ets_feature_t *admin_ets, 3963 IN const u32_t *pg_bw_tbl, 3964 IN const u32_t *pri_pg, 3965 IN const u8_t bw_tbl_size, 3966 IN const u8_t pri_pg_size ) 3967 { 3968 u8_t i = 0; 3969 3970 DbgBreakIf(DCBX_MAX_NUM_PG_BW_ENTRIES != bw_tbl_size); 3971 3972 for(i=0; i < DCBX_MAX_NUM_PG_BW_ENTRIES ;i++) 3973 { 3974 DCBX_PG_BW_SET(admin_ets->pg_bw_tbl, 3975 i, 3976 pg_bw_tbl[i]); 3977 } 3978 3979 DbgBreakIf(DCBX_MAX_NUM_PRI_PG_ENTRIES != pri_pg_size); 3980 3981 for(i=0; i < DCBX_MAX_NUM_PRI_PG_ENTRIES; i++) 3982 { 3983 DCBX_PRI_PG_SET(admin_ets->pri_pg_tbl, 3984 i, 3985 pri_pg[i]); 3986 } 3987 } 3988 /** 3989 * @description 3990 * 3991 * @param pdev 3992 * @param ets 3993 * @param ets_params 3994 * 3995 * @return lm_status_t 3996 */ 3997 lm_status_t 3998 lm_dcbx_ie_admin_mib_update_runtime_ets(IN lm_device_t *pdev, 3999 OUT dcbx_ets_feature_t *admin_ets, 4000 IN const dcb_ets_tsa_param_t *os_ets_params, 4001 IN const u32_t flags 4002 ) 4003 { 4004 u32_t pg_bw_tbl[DCBX_MAX_NUM_PG_BW_ENTRIES] = {0}; 4005 u32_t pri_pg[DCBX_MAX_NUM_PRI_PG_ENTRIES] = {0}; 4006 u8_t pri = 0; 4007 u8_t tc_entry = 0; 4008 4009 ASSERT_STATIC(DCBX_MAX_NUM_PRI_PG_ENTRIES == DCBX_MAX_NUM_PG_BW_ENTRIES); 4010 4011 ASSERT_STATIC(ARRSIZE(os_ets_params->priority_assignment_table) == 4012 DCBX_MAX_NUM_PG_BW_ENTRIES); 4013 4014 ASSERT_STATIC(ARRSIZE(os_ets_params->tc_bw_assignment_table) == 4015 DCBX_MAX_NUM_PRI_PG_ENTRIES); 4016 4017 ASSERT_STATIC(ARRSIZE(os_ets_params->tsa_assignment_table) == 4018 DCBX_MAX_NUM_PRI_PG_ENTRIES); 4019 4020 if(0 == GET_FLAGS(flags, DCB_PARAMS_ETS_ENABLED)) 4021 { 4022 // All pri_pg point to entry 0 4023 pg_bw_tbl[0] = 100; 4024 } 4025 else 4026 { 4027 // Prepare parameters from OS to standard config. 4028 for(pri = 0 ; 4029 pri < ARRSIZE(os_ets_params->priority_assignment_table); 4030 pri++) 4031 { 4032 tc_entry = os_ets_params->priority_assignment_table[pri]; 4033 4034 if(TSA_ASSIGNMENT_DCB_TSA_STRICT == os_ets_params->tsa_assignment_table[tc_entry]) 4035 { 4036 // pg_bw_tbl isn't relevant for strict priority 4037 pri_pg[pri] = DCBX_STRICT_PRI_PG; 4038 } 4039 else if(TSA_ASSIGNMENT_DCB_TSA_ETS == os_ets_params->tsa_assignment_table[tc_entry]) 4040 { 4041 pri_pg[pri] = tc_entry; 4042 pg_bw_tbl[tc_entry] = os_ets_params->tc_bw_assignment_table[tc_entry]; 4043 } 4044 else 4045 { 4046 DbgBreakMsg("lm_dcbx_get_ets_ieee_feature parameters are check before " 4047 "this should not happen"); 4048 // For retail 4049 return LM_STATUS_FAILURE; 4050 } 4051 } 4052 } 4053 4054 // Update MCP. 4055 lm_dcbx_admin_mib_update_ets_param( 4056 pdev, 4057 admin_ets, 4058 pg_bw_tbl, 4059 pri_pg, 4060 ARRSIZE(pg_bw_tbl) , 4061 ARRSIZE(pri_pg)); 4062 4063 return LM_STATUS_SUCCESS; 4064 } 4065 /** 4066 * Update PFC admin MIB 4067 * @param pdev 4068 * @param pfc 4069 * @param pfc_params 4070 * @param flags 4071 * 4072 * @return STATIC lm_status_t 4073 */ 4074 STATIC lm_status_t 4075 lm_dcbx_ie_admin_mib_pfc(IN lm_device_t *pdev, 4076 INOUT dcbx_pfc_feature_t *pfc, 4077 IN const dcb_pfc_param_t *pfc_params, 4078 IN const u32_t flags 4079 ) 4080 { 4081 if(GET_FLAGS(flags, DCB_PARAMS_PFC_ENABLED)) 4082 { 4083 pfc->pri_en_bitmap =(u8_t)pfc_params->pfc_enable; 4084 } 4085 else 4086 { 4087 pfc->pri_en_bitmap = 0; 4088 } 4089 4090 return LM_STATUS_SUCCESS; 4091 } 4092 /** 4093 * 4094 * @param pdev 4095 * @param p_admin_mib_offset 4096 * 4097 * @return STATIC lm_status_t 4098 */ 4099 STATIC lm_status_t 4100 lm_dcbx_get_admin_mib_offset( IN lm_device_t *pdev, 4101 OUT u32_t *p_admin_mib_offset) 4102 { 4103 u32_t dcbx_lldp_params_offset = SHMEM_LLDP_DCBX_PARAMS_NONE; 4104 const u32_t dcbx_lldp_params_field_offset = OFFSETOF(shmem2_region_t,dcbx_lldp_params_offset); 4105 lm_status_t lm_status = LM_STATUS_SUCCESS; 4106 4107 lm_dcbx_read_shmem2_mcp_fields( pdev, 4108 dcbx_lldp_params_field_offset, 4109 &dcbx_lldp_params_offset); 4110 4111 if (SHMEM_LLDP_DCBX_PARAMS_NONE == dcbx_lldp_params_offset) 4112 { 4113 DbgBreakMsg("lm_dcbx_read_admin_mib couldn't read mcp offset "); 4114 return LM_STATUS_FAILURE; 4115 } 4116 4117 *p_admin_mib_offset = LM_DCBX_ADMIN_MIB_OFFSET(pdev ,dcbx_lldp_params_offset); 4118 4119 return lm_status; 4120 } 4121 /** 4122 * 4123 * @param pdev 4124 * @param p_admin_mib 4125 * @param p_admin_mib_offset 4126 * 4127 * @return STATIC lm_status_t 4128 */ 4129 STATIC lm_status_t 4130 lm_dcbx_read_admin_mib( IN lm_device_t *pdev, 4131 OUT lldp_admin_mib_t *p_admin_mib, 4132 OUT u32_t *p_admin_mib_offset) 4133 { 4134 u32_t i = 0; 4135 u32_t *buff = NULL ; 4136 lm_status_t lm_status = LM_STATUS_SUCCESS; 4137 4138 lm_status = lm_dcbx_get_admin_mib_offset( pdev, 4139 p_admin_mib_offset); 4140 4141 if(LM_STATUS_SUCCESS != lm_status) 4142 { 4143 DbgBreakMsg("lm_dcbx_read_admin_mib: lm_dcbx_get_admin_mib_offset failed "); 4144 return lm_status; 4145 } 4146 4147 buff = (u32_t *)p_admin_mib; 4148 //Read the data first 4149 for(i=0 ;i < sizeof(lldp_admin_mib_t); i+=4, buff++) 4150 { 4151 *buff = REG_RD(pdev, 4152 ((*p_admin_mib_offset) + i)); 4153 } 4154 4155 return lm_status; 4156 } 4157 4158 /** 4159 * @description 4160 * Update admin MIN and notify MCP on the changes. 4161 * @param pdev 4162 * @param dcb_params 4163 * @param mf_cfg_offset_value 4164 * 4165 * @return STATIC lm_status_t 4166 */ 4167 STATIC lm_status_t 4168 lm_dcbx_ie_admin_mib_updated_runtime(IN lm_device_t *pdev, 4169 IN const dcb_indicate_event_params_t *dcb_params, 4170 OUT u8_t *classif_change_mcp_not_aware, 4171 OUT u8_t *is_ets_admin_updated 4172 ) 4173 { 4174 lldp_admin_mib_t admin_mib = {0}; 4175 u32_t i = 0; 4176 u32_t *buff = NULL ; 4177 lm_status_t lm_status = LM_STATUS_SUCCESS; 4178 u32_t fw_resp = 0; 4179 u32_t admin_mib_offset = 0; 4180 u8_t is_mfw_cfg = FALSE; 4181 const u32_t willing_flags = DCBX_ETS_WILLING | DCBX_PFC_WILLING | DCBX_APP_WILLING; 4182 4183 // Use original admin MIB not updated by BACS 4184 mm_memcpy(&admin_mib, &pdev->dcbx_info.admin_mib_org, sizeof(admin_mib)); 4185 4186 if(GET_FLAGS(dcb_params->flags, DCB_PARAMS_WILLING)) 4187 { 4188 SET_FLAGS(admin_mib.ver_cfg_flags,willing_flags); 4189 } 4190 else 4191 { 4192 RESET_FLAGS(admin_mib.ver_cfg_flags,willing_flags); 4193 } 4194 4195 lm_status = lm_dcbx_ie_admin_mib_update_runtime_ets(pdev, 4196 &admin_mib.features.ets, 4197 &dcb_params->ets_params, 4198 dcb_params->flags); 4199 4200 if(LM_STATUS_SUCCESS != lm_status) 4201 { 4202 DbgBreakMsg("lm_dcbx_ie_admin_mib_update_runtime_ets function failed "); 4203 } 4204 else 4205 { 4206 *is_ets_admin_updated = TRUE; 4207 is_mfw_cfg = TRUE; 4208 } 4209 4210 lm_status = lm_dcbx_ie_admin_mib_pfc(pdev, 4211 &admin_mib.features.pfc, 4212 &dcb_params->pfc_params, 4213 dcb_params->flags); 4214 4215 if(LM_STATUS_SUCCESS != lm_status) 4216 { 4217 DbgBreakMsg("lm_dcbx_ie_admin_mib_update_runtime_ets function failed "); 4218 } 4219 else 4220 { 4221 is_mfw_cfg = TRUE; 4222 } 4223 4224 lm_status = lm_dcbx_ie_admin_mib_classif_wrapper(pdev, 4225 &admin_mib.features.app, 4226 &dcb_params->classif_params, 4227 classif_change_mcp_not_aware, 4228 dcb_params->flags); 4229 4230 if(LM_STATUS_SUCCESS != lm_status) 4231 { 4232 DbgBreakMsg("lm_dcbx_ie_admin_mib_update_runtime_classif function failed "); 4233 } 4234 else 4235 { 4236 is_mfw_cfg = TRUE; 4237 } 4238 4239 if(TRUE == is_mfw_cfg) 4240 { 4241 // There is a configuration done to MCP that was done by OS. 4242 lm_dcbx_config_drv_flags( 4243 pdev, 4244 lm_dcbx_drv_flags_set_bit, 4245 DRV_FLAGS_DCB_MFW_CONFIGURED); 4246 4247 lm_status = lm_dcbx_get_admin_mib_offset( pdev, 4248 &admin_mib_offset); 4249 4250 // Write the data back. 4251 buff = (u32_t *)&admin_mib; 4252 for(i=0 ; i< sizeof(lldp_admin_mib_t); i+=4,buff++) 4253 { 4254 REG_WR(pdev, (admin_mib_offset + i) , *buff); 4255 } 4256 4257 // update MCP 4258 lm_status = lm_mcp_cmd_send_recieve( pdev, 4259 lm_mcp_mb_header, 4260 DRV_MSG_CODE_DCBX_ADMIN_PMF_MSG, 4261 0, 4262 MCP_CMD_DEFAULT_TIMEOUT, 4263 &fw_resp ) ; 4264 4265 DbgBreakIf( lm_status != LM_STATUS_SUCCESS ); 4266 } 4267 4268 return lm_status; 4269 } 4270 4271 /******************************************************************************* 4272 * Description: Update admin MIB that changes deafault DCBX configuration 4273 * "admin_dcbx_enable" and "dcb_enable" are stand alone registry keys 4274 * (if present will always be valid and not ignored), for all other 4275 * DCBX registry set only if the entire DCBX registry set is present 4276 * and differ from 0xFFFFFFFF (invalid value) the DCBX registry 4277 * parameters are taken, otherwise the registry key set is ignored.) 4278 * (Expect "admin_dcbx_enable" and "dcb_enable") 4279 * Return: 4280 ******************************************************************************/ 4281 STATIC void 4282 lm_dcbx_admin_mib_updated_init(lm_device_t * pdev, 4283 u32_t mf_cfg_offset_value) 4284 { 4285 lldp_admin_mib_t admin_mib = {0}; 4286 u32_t i = 0; 4287 u8_t next_free_app_id_entry = 0; /*used for not predifined entries*/ 4288 u32_t *buff = NULL ; 4289 lm_status_t lm_status = LM_STATUS_SUCCESS; 4290 u32_t offset = 0; 4291 4292 lm_status = lm_dcbx_read_admin_mib( pdev, 4293 &admin_mib, 4294 &offset); 4295 4296 if(LM_STATUS_SUCCESS != lm_status) 4297 { 4298 DbgBreakMsg(" lm_dcbx_admin_mib_updated_init lm_dcbx_read_admin_mib failed "); 4299 } 4300 DbgBreakIf(offset != LM_DCBX_ADMIN_MIB_OFFSET(pdev, mf_cfg_offset_value)); 4301 4302 if(DCBX_CONFIG_INV_VALUE != 4303 pdev->params.dcbx_config_params.admin_dcbx_enable) 4304 { 4305 if(pdev->params.dcbx_config_params.admin_dcbx_enable) 4306 { 4307 SET_FLAGS(admin_mib.ver_cfg_flags,DCBX_DCBX_ENABLED); 4308 } 4309 else 4310 { 4311 RESET_FLAGS(admin_mib.ver_cfg_flags,DCBX_DCBX_ENABLED); 4312 } 4313 } 4314 lm_status = lm_dcbx_init_check_params_valid(pdev, 4315 (u32_t *)(&(pdev->params.dcbx_config_params.overwrite_settings)), 4316 ((sizeof(pdev->params.dcbx_config_params)- 4317 OFFSETOF(config_dcbx_params_t , overwrite_settings))/sizeof(u32_t))); 4318 4319 if((LM_STATUS_SUCCESS == lm_status)&& 4320 (OVERWRITE_SETTINGS_ENABLE == pdev->params.dcbx_config_params.overwrite_settings)) 4321 { 4322 RESET_FLAGS(admin_mib.ver_cfg_flags,DCBX_CEE_VERSION_MASK); 4323 admin_mib.ver_cfg_flags |= 4324 (pdev->params.dcbx_config_params.admin_dcbx_version << DCBX_CEE_VERSION_SHIFT) & DCBX_CEE_VERSION_MASK; 4325 4326 admin_mib.features.ets.enabled = (u8_t) 4327 pdev->params.dcbx_config_params.admin_ets_enable; 4328 4329 4330 admin_mib.features.pfc.enabled =(u8_t) 4331 pdev->params.dcbx_config_params.admin_pfc_enable; 4332 4333 4334 //FOR IEEE pdev->params.dcbx_config_params.admin_tc_supported_tx_enable 4335 if(pdev->params.dcbx_config_params.admin_ets_configuration_tx_enable) 4336 { 4337 SET_FLAGS(admin_mib.ver_cfg_flags,DCBX_ETS_CONFIG_TX_ENABLED); 4338 } 4339 else 4340 { 4341 RESET_FLAGS(admin_mib.ver_cfg_flags,DCBX_ETS_CONFIG_TX_ENABLED); 4342 } 4343 //For IEEE admin_ets_recommendation_tx_enable 4344 4345 if(pdev->params.dcbx_config_params.admin_pfc_tx_enable) 4346 { 4347 SET_FLAGS(admin_mib.ver_cfg_flags,DCBX_PFC_CONFIG_TX_ENABLED); 4348 } 4349 else 4350 { 4351 RESET_FLAGS(admin_mib.ver_cfg_flags,DCBX_PFC_CONFIG_TX_ENABLED); 4352 } 4353 4354 if(pdev->params.dcbx_config_params.admin_application_priority_tx_enable) 4355 { 4356 SET_FLAGS(admin_mib.ver_cfg_flags,DCBX_APP_CONFIG_TX_ENABLED); 4357 } 4358 else 4359 { 4360 RESET_FLAGS(admin_mib.ver_cfg_flags,DCBX_APP_CONFIG_TX_ENABLED); 4361 } 4362 4363 4364 if(pdev->params.dcbx_config_params.admin_ets_willing) 4365 { 4366 SET_FLAGS(admin_mib.ver_cfg_flags,DCBX_ETS_WILLING); 4367 } 4368 else 4369 { 4370 RESET_FLAGS(admin_mib.ver_cfg_flags,DCBX_ETS_WILLING); 4371 } 4372 //For IEEE admin_ets_reco_valid 4373 if(pdev->params.dcbx_config_params.admin_pfc_willing) 4374 { 4375 SET_FLAGS(admin_mib.ver_cfg_flags,DCBX_PFC_WILLING); 4376 } 4377 else 4378 { 4379 RESET_FLAGS(admin_mib.ver_cfg_flags,DCBX_PFC_WILLING); 4380 } 4381 4382 if(pdev->params.dcbx_config_params.admin_app_priority_willing) 4383 { 4384 SET_FLAGS(admin_mib.ver_cfg_flags,DCBX_APP_WILLING); 4385 } 4386 else 4387 { 4388 RESET_FLAGS(admin_mib.ver_cfg_flags,DCBX_APP_WILLING); 4389 } 4390 4391 lm_dcbx_admin_mib_update_ets_param( 4392 pdev, 4393 &admin_mib.features.ets, 4394 pdev->params.dcbx_config_params.admin_configuration_bw_percentage, 4395 pdev->params.dcbx_config_params.admin_configuration_ets_pg, 4396 ARRSIZE(pdev->params.dcbx_config_params.admin_configuration_bw_percentage) , 4397 ARRSIZE(pdev->params.dcbx_config_params.admin_configuration_ets_pg)); 4398 4399 //For IEEE admin_recommendation_bw_percentage 4400 //For IEEE admin_recommendation_ets_pg 4401 admin_mib.features.pfc.pri_en_bitmap = (u8_t)pdev->params.dcbx_config_params.admin_pfc_bitmap; 4402 4403 for(i = 0; i<ARRSIZE(pdev->params.dcbx_config_params.admin_priority_app_table); i++) 4404 { 4405 if(pdev->params.dcbx_config_params.admin_priority_app_table[i].valid) 4406 { 4407 lm_dcbx_admin_mib_update_app_pri(pdev, 4408 &admin_mib.features.app, 4409 &next_free_app_id_entry, 4410 (u16_t)pdev->params.dcbx_config_params.admin_priority_app_table[i].app_id, 4411 (u8_t)pdev->params.dcbx_config_params.admin_priority_app_table[i].traffic_type, 4412 (u8_t)pdev->params.dcbx_config_params.admin_priority_app_table[i].priority); 4413 } 4414 } 4415 4416 admin_mib.features.app.tc_supported = next_free_app_id_entry; 4417 admin_mib.features.app.default_pri = (u8_t)pdev->params.dcbx_config_params.admin_default_priority; 4418 4419 // There is a configuration set by BACS. 4420 lm_dcbx_config_drv_flags( 4421 pdev, 4422 lm_dcbx_drv_flags_set_bit, 4423 DRV_FLAGS_DCB_MFW_CONFIGURED); 4424 4425 } 4426 else 4427 { 4428 if(OVERWRITE_SETTINGS_ENABLE == pdev->params.dcbx_config_params.overwrite_settings) 4429 { 4430 pdev->params.dcbx_config_params.overwrite_settings = OVERWRITE_SETTINGS_INVALID; 4431 } 4432 4433 } 4434 4435 //Write the data. 4436 buff = (u32_t *)&admin_mib; 4437 for(i=0 ; i < sizeof(lldp_admin_mib_t); i+=4,buff++) 4438 { 4439 REG_WR(pdev, (offset + i) , *buff); 4440 } 4441 } 4442 /******************************************************************************* 4443 * Description: Update LLDP that changes deafault LLDP configuration. 4444 * Only if the entire LLDP registry set is present and differ from 4445 * 0xFFFFFFFF (invalid value) the LLDP registry parameters are taken, 4446 * otherwise the registry keys are ignored. 4447 * Return: 4448 * LM_STATUS_FAILURE - All/Some of the parameters could not be read. 4449 * LM_STATUS_SUCCESS - All the MIBs where read successfully. 4450 ******************************************************************************/ 4451 STATIC void 4452 lm_dcbx_init_lldp_updated_params(struct _lm_device_t * pdev, 4453 u32_t mf_cfg_offset_value) 4454 { 4455 4456 lldp_params_t lldp_params = {0}; 4457 u32_t i = 0; 4458 u32_t *buff = NULL ; 4459 lm_status_t lm_status = LM_STATUS_SUCCESS; 4460 u32_t offest = mf_cfg_offset_value + 4461 PORT_ID(pdev) * sizeof(lldp_params_t); 4462 4463 lm_status = lm_dcbx_init_check_params_valid(pdev, 4464 (u32_t *)(&(pdev->params.lldp_config_params)), 4465 (sizeof(pdev->params.lldp_config_params)/sizeof(u32_t))); 4466 4467 if((LM_STATUS_SUCCESS == lm_status)&& 4468 (OVERWRITE_SETTINGS_ENABLE == pdev->params.lldp_config_params.overwrite_settings)) 4469 { 4470 //Read the data first 4471 buff = (u32_t *)&lldp_params; 4472 for(i=0 ;i<sizeof(lldp_params_t); i+=4,buff++) 4473 { 4474 *buff = REG_RD(pdev, 4475 (offest+ i)); 4476 } 4477 lldp_params.msg_tx_hold = (u8_t)pdev->params.lldp_config_params.msg_tx_hold; 4478 lldp_params.msg_fast_tx_interval = (u8_t)pdev->params.lldp_config_params.msg_fast_tx; 4479 lldp_params.tx_crd_max = (u8_t)pdev->params.lldp_config_params.tx_credit_max; 4480 lldp_params.msg_tx_interval = (u8_t)pdev->params.lldp_config_params.msg_tx_interval; 4481 lldp_params.tx_fast = (u8_t)pdev->params.lldp_config_params.tx_fast; 4482 4483 //Write the data. 4484 buff = (u32_t *)&lldp_params; 4485 for(i=0 ;i<sizeof(lldp_params_t); i+=4,buff++) 4486 { 4487 REG_WR(pdev, (offest+ i) , *buff);//Change to write 4488 } 4489 } 4490 else 4491 { 4492 if(OVERWRITE_SETTINGS_ENABLE == pdev->params.lldp_config_params.overwrite_settings) 4493 { 4494 pdev->params.lldp_config_params.overwrite_settings = OVERWRITE_SETTINGS_INVALID; 4495 } 4496 4497 } 4498 4499 } 4500 /******************************************************************************* 4501 * Description: 4502 * Allocate physical memory for DCBX start ramrod 4503 * 4504 * Return: 4505 ******************************************************************************/ 4506 lm_status_t 4507 lm_dcbx_get_pfc_fw_cfg_phys_mem( 4508 IN struct _lm_device_t *pdev, 4509 IN const u8_t lm_cli_idx) 4510 { 4511 if (CHK_NULL(pdev->dcbx_info.pfc_fw_cfg_virt)) 4512 { 4513 pdev->dcbx_info.pfc_fw_cfg_virt = 4514 mm_alloc_phys_mem(pdev, 4515 sizeof(struct flow_control_configuration), 4516 &pdev->dcbx_info.pfc_fw_cfg_phys, 4517 0, 4518 lm_cli_idx); 4519 4520 if CHK_NULL(pdev->dcbx_info.pfc_fw_cfg_virt) 4521 { 4522 return LM_STATUS_RESOURCE; 4523 } 4524 } 4525 4526 return LM_STATUS_SUCCESS; 4527 } 4528 /** 4529 * @description 4530 * Called to clean dcbx info after D3 4531 * @param pdev 4532 * 4533 * @return lm_status_t 4534 */ 4535 lm_status_t 4536 lm_dcbx_init_info( 4537 IN lm_device_t *pdev 4538 ) 4539 { 4540 pdev->dcbx_info.is_enabled = FALSE; 4541 4542 return LM_STATUS_SUCCESS; 4543 } 4544 /******************************************************************************* 4545 * Description: 4546 * 4547 * 4548 * Return: 4549 ******************************************************************************/ 4550 lm_status_t 4551 lm_dcbx_free_resc( 4552 IN struct _lm_device_t *pdev 4553 ) 4554 { 4555 pdev->dcbx_info.pfc_fw_cfg_virt = NULL; 4556 pdev->dcbx_info.is_enabled = FALSE; 4557 return LM_STATUS_SUCCESS; 4558 } 4559 /** 4560 * lm_dcbx_ie_init_event_params 4561 * @param pdev 4562 * @param params 4563 * @param classif_table_size 4564 */ 4565 void 4566 lm_dcbx_ie_init_event_params( 4567 IN struct _lm_device_t *pdev, 4568 IN dcb_indicate_event_params_t *params, 4569 IN const u32_t classif_table_size) 4570 { 4571 params->flags = 0; 4572 4573 mm_mem_zero(¶ms->ets_params, sizeof(params->ets_params)); 4574 4575 mm_mem_zero(¶ms->pfc_params, sizeof(params->pfc_params)); 4576 4577 params->classif_params.classif_version = DCB_CLASSIFI_VER_SIMPLE_ELEM; 4578 params->classif_params.num_classif_elements = 0; 4579 4580 if((NULL != params->classif_params.classif_table) && 4581 classif_table_size) 4582 { 4583 mm_mem_zero( params->classif_params.classif_table, 4584 classif_table_size); 4585 } 4586 } 4587 /** 4588 * lm_dcbx_ie_init_params 4589 * 4590 * @param pdev 4591 * @param b_only_setup 4592 */ 4593 void 4594 lm_dcbx_ie_init_params( 4595 IN struct _lm_device_t *pdev, 4596 IN const u8_t b_only_setup) 4597 { 4598 lm_dcbx_indicate_event_t *indicate_event = &pdev->dcbx_info.indicate_event; 4599 4600 if (TRUE == b_only_setup) 4601 { 4602 lm_dcbx_ie_init_event_params(pdev, 4603 &indicate_event->local_params, 4604 LM_DCBX_IE_CLASSIF_TABLE_ALOC_SIZE_LOCAL); 4605 4606 lm_dcbx_ie_init_event_params(pdev, 4607 &indicate_event->remote_params, 4608 LM_DCBX_IE_CLASSIF_TABLE_ALOC_SIZE_REMOTE); 4609 4610 lm_dcbx_ie_init_event_params(pdev, 4611 &indicate_event->dcb_params_given_dbg, 4612 LM_DCBX_IE_CLASSIF_TABLE_ALOC_SIZE_DBG); 4613 } 4614 else 4615 { 4616 mm_mem_zero(indicate_event, sizeof(lm_dcbx_indicate_event_t)); 4617 indicate_event->lm_cli_idx = LM_CLI_IDX_MAX; 4618 } 4619 4620 indicate_event->ets_config_state = lm_dcbx_ets_config_state_cee; 4621 4622 indicate_event->is_ets_ieee_params_os_valid = FALSE; 4623 mm_mem_zero(&indicate_event->ets_ieee_params_os , 4624 sizeof(indicate_event->ets_ieee_params_os)); 4625 4626 indicate_event->ets_ieee_config_state = lm_dcbx_ets_ieee_config_not_valid; 4627 mm_mem_zero(&indicate_event->ets_ieee_params_config , 4628 sizeof(indicate_event->ets_ieee_params_config)); 4629 4630 indicate_event->iscsi_tcp_pri = LM_DCBX_ILLEGAL_PRI; 4631 4632 indicate_event->dcb_current_oper_state_bitmap = 0; 4633 4634 } 4635 /******************************************************************************* 4636 * Description: 4637 * Allocate physical memory for DCBX start ramrod 4638 * 4639 * Return: 4640 ******************************************************************************/ 4641 lm_status_t 4642 lm_dcbx_init_params( 4643 IN struct _lm_device_t *pdev, 4644 IN const u8_t b_only_setup) 4645 { 4646 lm_status_t lm_status = LM_STATUS_SUCCESS; 4647 u8_t lm_cli_idx = LM_CLI_IDX_MAX; 4648 u32_t dummy_offset = 0; 4649 4650 // All priorities are mapped by default to zero 4651 mm_mem_zero(pdev->dcbx_info.pri_to_cos, sizeof(pdev->dcbx_info.pri_to_cos)); 4652 4653 mm_mem_zero(&(pdev->params.dcbx_port_params), sizeof(pdev->params.dcbx_port_params)); 4654 4655 pdev->dcbx_info.dcbx_update_lpme_task_state = DCBX_UPDATE_TASK_STATE_FREE; 4656 pdev->dcbx_info.is_dcbx_neg_received = FALSE; 4657 4658 lm_dcbx_ie_init_params(pdev, b_only_setup); 4659 4660 // Should not be used in MF this is only a pach until MCP will know how to return to default 4661 lm_status = lm_dcbx_read_admin_mib( pdev, 4662 &pdev->dcbx_info.admin_mib_org, 4663 &dummy_offset); 4664 4665 if(LM_STATUS_SUCCESS != lm_status) 4666 { 4667 DbgBreakMsg(" lm_dcbx_admin_mib_updated_init lm_dcbx_read_admin_mib failed "); 4668 return lm_status; 4669 } 4670 4671 if(FALSE == b_only_setup) 4672 { 4673 lm_status = lm_dcbx_get_pfc_fw_cfg_phys_mem(pdev, lm_cli_idx); 4674 if(LM_STATUS_SUCCESS != lm_status ) 4675 { 4676 DbgBreakMsg("lm_dcbx_init_params : resource "); 4677 pdev->dcbx_info.dcbx_error |= DCBX_ERROR_RESOURCE; 4678 return lm_status; 4679 } 4680 } 4681 4682 4683 return lm_status; 4684 } 4685 4686 /** 4687 * @description 4688 * Set in a shared port memory place if DCBX completion was 4689 * received. Function is needed for PMF migration in order to 4690 * synchronize the new PMF that DCBX results has ended. 4691 * @param pdev 4692 * @param is_completion_recv 4693 */ 4694 void 4695 lm_dcbx_config_drv_flags( 4696 IN lm_device_t *pdev, 4697 IN const lm_dcbx_drv_flags_cmd_t drv_flags_cmd, 4698 IN const u32_t bit_drv_flags) 4699 { 4700 const u32_t drv_flags_offset = OFFSETOF(shmem2_region_t,drv_flags); 4701 u32_t drv_flags = 0; 4702 lm_status_t lm_status = LM_STATUS_SUCCESS; 4703 const u8_t port = PORT_ID(pdev); 4704 u32_t port_drv_flags = DRV_FLAGS_FILED_BY_PORT(bit_drv_flags, port); 4705 4706 if(!IS_PMF(pdev)) 4707 { 4708 DbgBreakMsg("lm_dcbx_check_drv_flags error only PMF can access this field "); 4709 return; 4710 } 4711 4712 lm_status = lm_hw_lock(pdev, HW_LOCK_RESOURCE_DRV_FLAGS, TRUE); 4713 4714 if(LM_STATUS_SUCCESS != lm_status) 4715 { 4716 DbgBreakMsg("lm_dcbx_set_comp_recv_on_port_bit lm_hw_lock failed "); 4717 return; 4718 } 4719 4720 lm_dcbx_read_shmem2_mcp_fields(pdev, 4721 drv_flags_offset, 4722 &drv_flags); 4723 4724 switch(drv_flags_cmd) 4725 { 4726 case lm_dcbx_drv_flags_set_bit: 4727 SET_FLAGS(drv_flags,port_drv_flags); 4728 break; 4729 case lm_dcbx_drv_flags_reset_bit: 4730 RESET_FLAGS(drv_flags,port_drv_flags); 4731 break; 4732 case lm_dcbx_drv_flags_reset_flags: 4733 port_drv_flags = DRV_FLAGS_GET_PORT_MASK(port); 4734 4735 RESET_FLAGS(drv_flags,port_drv_flags); 4736 break; 4737 default: 4738 DbgBreakMsg("lm_dcbx_set_comp_recv_on_port_bit : illegal drv_flags_cmd "); 4739 return; 4740 }; 4741 4742 lm_dcbx_write_shmem2_mcp_fields(pdev, 4743 drv_flags_offset, 4744 drv_flags); 4745 4746 lm_hw_unlock(pdev, HW_LOCK_RESOURCE_DRV_FLAGS); 4747 } 4748 /** 4749 * @description 4750 * Function is needed for PMF migration in order to synchronize 4751 * the new PMF that DCBX results has ended. 4752 * @param pdev 4753 * 4754 * @return u8_t 4755 * This function returns TRUE if DCBX completion received on 4756 * this port 4757 */ 4758 u8_t 4759 lm_dcbx_check_drv_flags( 4760 IN lm_device_t *pdev, 4761 IN const u32_t flags_bits_to_check) 4762 { 4763 const u32_t drv_flags_offset = OFFSETOF(shmem2_region_t,drv_flags); 4764 u32_t drv_flags = 0; 4765 u8_t is_flag_set = FALSE; 4766 const u8_t port = PORT_ID(pdev); 4767 const u32_t port_flags_to_check = DRV_FLAGS_FILED_BY_PORT(flags_bits_to_check, port); 4768 4769 if(!IS_PMF(pdev)) 4770 { 4771 DbgBreakMsg("lm_dcbx_check_drv_flags error only PMF can access this field "); 4772 return FALSE; 4773 } 4774 4775 lm_dcbx_read_shmem2_mcp_fields(pdev, 4776 drv_flags_offset, 4777 &drv_flags); 4778 4779 if(GET_FLAGS(drv_flags, port_flags_to_check)) 4780 { 4781 is_flag_set = TRUE; 4782 } 4783 4784 return is_flag_set; 4785 } 4786 /** 4787 * @description 4788 * 1. Make sure all the DCBX init parameters for this function 4789 * are correct. 4790 * 2. Register a set DCBX params in order to let the new PMF 4791 * migration function to know the current DCBX settings and that 4792 * the pdev varibales will mach the HW configuration. 4793 * for example in MF when DCBX is configured to static 4794 * configuration ELINK_FEATURE_CONFIG_PFC_ENABLED is set in pdev 4795 * (we get only one interrupt)of only the original 4796 * function.After PMF migration the first link updated will 4797 * cause the PFC state to be incompatible.The function that 4798 * become PMF doesn't have ELINK_FEATURE_CONFIG_PFC_ENABLED set 4799 * @param pdev 4800 */ 4801 void 4802 lm_dcbx_pmf_migration( 4803 IN struct _lm_device_t *pdev) 4804 { 4805 lm_status_t lm_status = LM_STATUS_SUCCESS; 4806 const u8_t is_completion_received_on_port = 4807 lm_dcbx_check_drv_flags(pdev, DRV_FLAGS_DCB_CONFIGURED); 4808 4809 DbgBreakIf(TRUE != IS_DCB_ENABLED(pdev)); 4810 4811 // We called lm_dcbx_init_params at the beginning 4812 // verify all the parameters are correct and that there is no error. 4813 DbgBreakIf(FALSE != pdev->dcbx_info.is_dcbx_neg_received); 4814 DbgBreakIf(DCBX_UPDATE_TASK_STATE_FREE != pdev->dcbx_info.dcbx_update_lpme_task_state); 4815 DbgBreakIf(CHK_NULL(pdev->dcbx_info.pfc_fw_cfg_virt)); 4816 4817 // for this function the only error possibole is that the pfc_fw_cfg_virt wasn't allocated. 4818 if((DCBX_ERROR_NO_ERROR != pdev->dcbx_info.dcbx_error) || 4819 (FALSE == IS_MULTI_VNIC(pdev))) 4820 { 4821 DbgBreakMsg("lm_dcbx_init : lm_mcp_cmd_send_recieve failed "); 4822 return; 4823 } 4824 4825 // If we received the DCBX parameters before on this port the new PMF 4826 // will read the current DCBX parameters 4827 if(FALSE == is_completion_received_on_port) 4828 { 4829 // DCBX parameters were not received before 4830 return; 4831 } 4832 // Register a set params in order to let the new PMF migration 4833 // function to know the current DCBX settings. 4834 // A side effect of this function be to set the DCBX parameters again, 4835 // but this is a must because in case of an error(or if we have an 4836 // innterrupt from MCP that eas not handled) the seetings that are 4837 // currently on the chip may not be equale to the local settings. 4838 lm_status = MM_REGISTER_LPME(pdev, 4839 lm_dcbx_init_lpme_set_params, 4840 TRUE, 4841 FALSE);// DCBX sends ramrods 4842 4843 if (LM_STATUS_SUCCESS != lm_status) 4844 { 4845 pdev->dcbx_info.dcbx_error |= DCBX_ERROR_REGISTER_LPME; 4846 // No rollback 4847 // Problem because if DCBX interrupt isn't receive the chip will be 4848 // stuck beacuse QM queues are stopped. 4849 // For release version this will call DCBX start that will restart QM queues. 4850 DbgBreakMsg("lm_dcbx_int : The chip QM queues are stuck until an interrupt from MCP"); 4851 } 4852 } 4853 /** 4854 * First check if DCBX is enabled on port.Old MCP that doesn't 4855 * support the field dcbx_en should not be used in 4 port 4856 * because if one port supports DCBX but the other does't, 4857 * driver can't tell the difference according to 4858 * dcbx_lldp_params_offset.(dcbx_lldp_params_offset is valid if 4859 * one port is enabled) 4860 * 4861 * After check that dcbx_lldp_params_offset is valid for 4862 * backward compatibility(until 4 port). 4863 * If dcbx_en isn't zero dcbx_lldp_params_offset must be vaild. 4864 * @param pdev 4865 * 4866 * @return u8_t 4867 */ 4868 u8_t 4869 lm_dcbx_port_enable_mcp(IN lm_device_t *pdev) 4870 { 4871 u32_t lldp_params_offset = SHMEM_LLDP_DCBX_PARAMS_NONE; 4872 const u32_t mcp_lldp_params_offset = OFFSETOF(shmem2_region_t,dcbx_lldp_params_offset); 4873 const u8_t port = PORT_ID(pdev); 4874 const u32_t dcbx_en_offset = OFFSETOF(shmem2_region_t,dcbx_en[port]); 4875 u32_t read_dcbx_en = 0; 4876 4877 if(LM_SHMEM2_HAS(pdev, dcbx_en[port])) 4878 { 4879 LM_SHMEM2_READ(pdev, dcbx_en_offset, &read_dcbx_en); 4880 4881 if(0 == read_dcbx_en) 4882 { 4883 return FALSE; 4884 } 4885 } 4886 else 4887 { 4888 DbgMessage(pdev, FATAL, "lm_dcbx_port_enable_mcp: Old MCP a new driver requires" 4889 "a new MFW for knowing if DCBX is enabled in 4 port mode.\n"); 4890 } 4891 4892 lm_dcbx_read_shmem2_mcp_fields( pdev, 4893 mcp_lldp_params_offset, 4894 &lldp_params_offset); 4895 4896 DbgBreakIf((0 != read_dcbx_en) && 4897 (SHMEM_LLDP_DCBX_PARAMS_NONE == lldp_params_offset)); 4898 4899 return (SHMEM_LLDP_DCBX_PARAMS_NONE != lldp_params_offset); 4900 } 4901 /******************************************************************************* 4902 * Description: 4903 * The PMF function starts the DCBX negotiation after sending the 4904 * MIB DRV_MSG_LLDP_PMF_MSG with new LLDP/DCBX configurations if available. 4905 * The PMF will call the function dcbx_stop_Hw_TX () that will ensure 4906 * that no traffic can be sent. (The driver will send a ramrod to the 4907 * FW that will stop all the queues in the QM) 4908 * After 1 second (a timer elapsed) if DCBX negotiation didn't end 4909 * (pdev.vars.dcbx_neg_received =0) and link is up a WI lm_dcbx_resume_TX() 4910 * is scheduled . 4911 * In WI read the configuration from local MIB and set DCBX parameters 4912 * to the value in local_MIB. 4913 * 4914 * Return: 4915 ******************************************************************************/ 4916 void 4917 lm_dcbx_init(IN struct _lm_device_t *pdev, 4918 IN const u8_t b_only_setup) 4919 { 4920 u32_t fw_resp = 0 ; 4921 lm_status_t lm_status = LM_STATUS_FAILURE ; 4922 u32_t dcbx_lldp_params_offset = SHMEM_LLDP_DCBX_PARAMS_NONE; 4923 const u32_t mcp_dcbx_lldp_params_offset = OFFSETOF(shmem2_region_t,dcbx_lldp_params_offset); 4924 u8_t is_mfw_config = FALSE; 4925 4926 DbgBreakIf(FALSE != IS_DCB_ENABLED(pdev)); 4927 4928 if(IS_DCB_SUPPORTED(pdev)) 4929 {// DCBX is supported on E1H. E2 only in 2 port mode. 4930 if (lm_dcbx_port_enable_mcp(pdev)) 4931 {// DCBX supported in MCP 4932 4933 lm_status = lm_dcbx_init_params(pdev, b_only_setup); 4934 if(LM_STATUS_SUCCESS != lm_status) 4935 {// If dcbx pfc_fw_cfg could not be allocated DCBX isn't supported 4936 return; 4937 } 4938 4939 if(IS_PMF_ORIGINAL(pdev)) 4940 {//Only the PMF starts and handles 4941 pdev->dcbx_info.is_enabled = TRUE; 4942 4943 lm_dcbx_read_shmem2_mcp_fields( pdev, 4944 mcp_dcbx_lldp_params_offset, 4945 &dcbx_lldp_params_offset); 4946 4947 DbgBreakIf(SHMEM_LLDP_DCBX_PARAMS_NONE == dcbx_lldp_params_offset); 4948 4949 lm_dcbx_init_lldp_updated_params( pdev, 4950 dcbx_lldp_params_offset); 4951 4952 lm_dcbx_admin_mib_updated_init( pdev, 4953 dcbx_lldp_params_offset); 4954 4955 lm_status = lm_mcp_cmd_send_recieve( pdev, 4956 lm_mcp_mb_header, 4957 DRV_MSG_CODE_DCBX_ADMIN_PMF_MSG, 4958 0, 4959 MCP_CMD_DEFAULT_TIMEOUT, 4960 &fw_resp ) ; 4961 4962 if( lm_status != LM_STATUS_SUCCESS ) 4963 { 4964 pdev->dcbx_info.dcbx_error |= DCBX_ERROR_MCP_CMD_FAILED; 4965 DbgBreakMsg("lm_dcbx_init : lm_mcp_cmd_send_recieve failed "); 4966 return; 4967 } 4968 is_mfw_config = lm_dcbx_check_drv_flags(pdev, DRV_FLAGS_DCB_MFW_CONFIGURED); 4969 4970 if(TRUE == is_mfw_config) 4971 { 4972 lm_status = MM_REGISTER_LPME(pdev, 4973 lm_dcbx_init_lpme_set_params, 4974 TRUE, 4975 FALSE);// DCBX sends ramrods 4976 4977 if (LM_STATUS_SUCCESS != lm_status) 4978 { 4979 pdev->dcbx_info.dcbx_error |= DCBX_ERROR_REGISTER_LPME; 4980 // No rollback 4981 // Problem because if DCBX interrupt isn't receive the chip will be 4982 // stuck beacuse QM queues are stopped. 4983 // For release version this will call DCBX start that will restart QM queues. 4984 DbgBreakMsg("lm_dcbx_int : The chip QM queues are stuck until an interrupt from MCP"); 4985 } 4986 } 4987 }//PMF Original 4988 else 4989 { 4990 pdev->dcbx_info.is_enabled = TRUE; 4991 if(IS_PMF_MIGRATION(pdev)) 4992 { 4993 // Send an attention on this Function. 4994 // We create an interrupt on this function to make sure we will wake up another time 4995 // to send the MCP ACK. 4996 LM_GENERAL_ATTN_INTERRUPT_SET(pdev,FUNC_ID(pdev)); 4997 } 4998 } 4999 }// DCBX supported in MCP 5000 } //DCBX enabled. 5001 } 5002 /******************************************************************************* 5003 * Description: 5004 * 5005 * Return: 5006 ******************************************************************************/ 5007 static void 5008 lm_dcbx_init_set_params_invalid(u32_t * buff_check, 5009 u32_t buff_size) 5010 { 5011 u32_t i=0; 5012 for (i=0 ; i < buff_size ; i++,buff_check++) 5013 { 5014 *buff_check = DCBX_CONFIG_INV_VALUE; 5015 } 5016 } 5017 /** 5018 * @description 5019 * Init dcbx init default params this function should be called 5020 * once before any other DCBX function is called. 5021 * @param pdev 5022 */ 5023 void 5024 lm_dcbx_init_default_params(lm_device_t *pdev) 5025 { 5026 // Init dcbx and lldp params 5027 5028 lm_dcbx_init_set_params_invalid((u32_t *)(&(pdev->params.lldp_config_params)), 5029 (sizeof(pdev->params.lldp_config_params)/sizeof(u32_t))); 5030 5031 lm_dcbx_init_set_params_invalid((u32_t *)(&(pdev->params.dcbx_config_params)), 5032 (sizeof(pdev->params.dcbx_config_params)/sizeof(u32_t))); 5033 5034 pdev->params.dcbx_config_params.dcb_enable = 1; //DCB by default is disabled 5035 pdev->params.dcbx_config_params.admin_dcbx_enable = 1; //DCBX by default is enabled 5036 5037 if((!(CHIP_IS_E1x(pdev))) && 5038 IS_PFDEV(pdev)) 5039 { 5040 pdev->params.b_dcb_indicate_event = TRUE; 5041 } 5042 } 5043 5044 /**********************end DCBX INIT FUNCTIONS**************************************/ 5045 5046 /**********************start DCBX UPDATE FUNCTIONS**************************************/ 5047 /******************************************************************************* 5048 * Description: 5049 * Any DCBX update will be treated as a runtime change. 5050 * Runtime changes can take more than 1 second and can't be handled 5051 * from DPC. 5052 * When the PMF detects a DCBX update it will schedule a WI that 5053 * will handle the job. 5054 * This function should be called in PASSIVE IRQL (Currently called from 5055 * DPC) and in mutual exclusion any acces to lm_dcbx_stop_HW_TX 5056 * /lm_dcbx_resume_HW_TX. 5057 * 5058 * Return: 5059 ******************************************************************************/ 5060 void 5061 lm_dcbx_update_lpme_set_params(struct _lm_device_t *pdev) 5062 { 5063 u32_t offset = 0; 5064 u32_t drv_status = 0; 5065 lm_status_t lm_status = LM_STATUS_SUCCESS; 5066 5067 offset = OFFSETOF(shmem_region_t, func_mb[FUNC_MAILBOX_ID(pdev)].drv_status) ; 5068 5069 // drv_status 5070 LM_SHMEM_READ(pdev, 5071 offset, 5072 &drv_status); 5073 5074 if((IS_PMF(pdev))&& 5075 (GET_FLAGS( drv_status, DRV_STATUS_DCBX_NEGOTIATION_RESULTS))&& 5076 (DCBX_UPDATE_TASK_STATE_SCHEDULE == pdev->dcbx_info.dcbx_update_lpme_task_state)) 5077 { 5078 // No lock is needed to be taken because lm_dcbx_set_params is only called from a WI 5079 lm_status = lm_dcbx_set_params_and_read_mib(pdev, 5080 FALSE, 5081 TRUE); 5082 5083 DbgBreakIf(LM_STATUS_SUCCESS != lm_status); 5084 5085 pdev->dcbx_info.dcbx_update_lpme_task_state = 5086 DCBX_UPDATE_TASK_STATE_HANDLED; 5087 // Send an attention on this Function. 5088 // We create an interrupt on this function to make sure we will wake up another time 5089 // to send the MCP ACK. 5090 LM_GENERAL_ATTN_INTERRUPT_SET(pdev,FUNC_ID(pdev)); 5091 } 5092 else 5093 { 5094 DbgBreakMsg("lm_dcbx_update_lpme_set_params error"); 5095 } 5096 } 5097 /**********************end DCBX UPDATE FUNCTIONS**************************************/ 5098 5099 /** 5100 * @description 5101 * Enable indicate event to upper layer 5102 * @param pdev 5103 */ 5104 void lm_dcbx_ie_update_state( 5105 INOUT struct _lm_device_t * pdev, 5106 IN const u8_t is_en) 5107 { 5108 pdev->dcbx_info.is_indicate_event_en = is_en; 5109 } 5110 /** 5111 * @description 5112 * 5113 * @param pdev 5114 * 5115 * @return u8 5116 */ 5117 u8_t lm_dcbx_cos_max_num( 5118 INOUT const struct _lm_device_t * pdev) 5119 { 5120 u8_t cos_max_num = 0; 5121 5122 if(CHIP_IS_E3B0(pdev)) 5123 { 5124 cos_max_num = DCBX_COS_MAX_NUM_E3B0; 5125 } 5126 else 5127 { 5128 cos_max_num = DCBX_COS_MAX_NUM_E2E3A0; 5129 } 5130 5131 return cos_max_num; 5132 } 5133 /** 5134 * @description 5135 * Validate the PFC parameters that were received can be 5136 * configured. The parameters will later be configured in WI. 5137 * @param pdev 5138 * @param pfc_params 5139 * @param dcbx_neg_res_offset - After the offset was read 5140 * correctly from Shmem. 5141 * 5142 * @return STATIC lm_status_t 5143 */ 5144 STATIC lm_status_t 5145 lm_dcbx_ie_runtime_params_updated_validate_pfc( 5146 INOUT lm_device_t *pdev, 5147 IN const dcb_pfc_param_t *pfc_params 5148 ) 5149 { 5150 lm_status_t lm_status = LM_STATUS_SUCCESS; 5151 5152 if(FALSE == pdev->dcbx_info.is_indicate_event_en) 5153 { 5154 DbgBreakMsg("lm_dcbx_runtime_params_updated_validate_pfc called but is_indicate_event_en is false"); 5155 return LM_STATUS_FAILURE; 5156 } 5157 5158 return lm_status; 5159 } 5160 /** 5161 * @description 5162 * Validate the ETS parameters that were received can be 5163 * configured. The parameters will later be configured in WI. 5164 * @param pdev 5165 * @param ets_params 5166 * 5167 * @return STATIC lm_status_t 5168 */ 5169 STATIC lm_status_t 5170 lm_dcbx_ie_params_updated_validate_ets( 5171 INOUT lm_device_t *pdev, 5172 IN const dcb_ets_tsa_param_t *ets_params 5173 ) 5174 { 5175 lm_status_t lm_status = LM_STATUS_SUCCESS; 5176 const u8_t cos_max_num = lm_dcbx_cos_max_num(pdev); 5177 u8_t i = 0; 5178 u8_t tc_entry = 0; 5179 u8_t tc_entry_bitmap = 0; 5180 u8_t tc_used_bitmap = 0; 5181 u8_t num_of_tc_used = 0; 5182 5183 if(cos_max_num < ets_params->num_traffic_classes ) 5184 { 5185 DbgBreakMsg("lm_dcbx_runtime_params_updated_validate_ets num_traffic_classes can't be larger" 5186 "than cos_max_num"); 5187 return LM_STATUS_FAILURE; 5188 } 5189 5190 if(LM_DCBX_IE_IS_ETS_DISABLE(ets_params->num_traffic_classes)) 5191 { 5192 DbgMessage(pdev, INFORM, "ETS is disabled other ETS paramters not checked \n"); 5193 5194 return LM_STATUS_SUCCESS; 5195 } 5196 5197 for(i = 0; i < ARRSIZE(ets_params->priority_assignment_table); i++) 5198 { 5199 //cos_max_num 5200 tc_entry = ets_params->priority_assignment_table[i]; 5201 if(tc_entry >= DCBX_MAX_NUM_PG_BW_ENTRIES) 5202 { 5203 DbgBreakMsg("lm_dcbx_runtime_params_updated_validate_ets a tc_entry can't be larger" 5204 "than the number of TC supported"); 5205 return LM_STATUS_FAILURE; 5206 } 5207 5208 tc_entry_bitmap = (1 << tc_entry); 5209 // Count the number of TC entries given and fill the appropriate COS entry. 5210 if(0 == (tc_used_bitmap & tc_entry_bitmap)) 5211 { 5212 // New TC add it to the bitmask 5213 tc_used_bitmap |= tc_entry_bitmap; 5214 num_of_tc_used++; 5215 DbgBreakIf(cos_max_num < num_of_tc_used); 5216 } 5217 5218 5219 switch(ets_params->tsa_assignment_table[tc_entry]) 5220 { 5221 case TSA_ASSIGNMENT_DCB_TSA_STRICT: 5222 case TSA_ASSIGNMENT_DCB_TSA_ETS: //fall through 5223 // Entry can be handled by VBD 5224 break; 5225 5226 case TSA_ASSIGNMENT_DCB_TSA_CBS: 5227 DbgBreakMsg("TSA_ASSIGNMENT_DCB_TSA_CBS value isn't supported by VBD"); 5228 return LM_STATUS_INVALID_PARAMETER; 5229 break; 5230 default: 5231 DbgBreakMsg("illegal value for tsa_assignment_table"); 5232 break; 5233 } 5234 } 5235 5236 if(ets_params->num_traffic_classes < num_of_tc_used ) 5237 { 5238 if(0 == pdev->params.lm_dcb_dont_break_bad_oid) 5239 { 5240 DbgBreakMsg("OS gave more TC than mentioned in num_traffic_classes"); 5241 } 5242 return LM_STATUS_INVALID_PARAMETER; 5243 } 5244 5245 return lm_status; 5246 } 5247 /** 5248 * @description 5249 * For classification entries that will be supported are 5250 * returned with the flag DCB_CLASSIF_ENFORCED_BY_VBD set. 5251 * 5252 * Set the flag in classification entries that do not conflict 5253 * with the remote settings and is supported by the miniport, 5254 * and clear the flag in classification entries that do conflict 5255 * with remote settings or is not supported by the miniport. 5256 * @param pdev 5257 * @param classif_params 5258 * @param mcp_dcbx_neg_res_offset 5259 * 5260 * @return STATIC lm_status_t 5261 */ 5262 STATIC lm_status_t 5263 lm_dcbx_ie_classif_entries_validate_and_set_enforced( 5264 IN struct _lm_device_t *pdev, 5265 INOUT dcb_classif_params_t *classif_params) 5266 { 5267 dcb_classif_elem_t *p_classif_elem = classif_params->classif_table; 5268 lm_status_t lm_status = LM_STATUS_SUCCESS; 5269 u8_t i = 0; 5270 5271 if(DCB_CLASSIFI_VER_SIMPLE_ELEM != classif_params->classif_version) 5272 { 5273 DbgBreakMsg("lm_dcbx_runtime_params_updated_en_classif_entries : classif_version not supported "); 5274 return LM_STATUS_FAILURE; 5275 } 5276 5277 for(i = 0; i < classif_params->num_classif_elements; i++,p_classif_elem++) 5278 { 5279 5280 if(NULL == p_classif_elem) 5281 { 5282 DbgBreakMsg("lm_dcbx_runtime_params_updated_en_classif_entries : p_classif_elem is null "); 5283 return LM_STATUS_FAILURE; 5284 } 5285 5286 if(DCB_ACTION_PRIORITY != p_classif_elem->action_selector) 5287 { 5288 // VBD only supports condition_selector that is based on priority 5289 continue; 5290 } 5291 switch(p_classif_elem->condition_selector) 5292 { 5293 case DCB_CONDITION_DEFAULT: 5294 // Must be the first entry 5295 DbgBreakIf(0 != i); 5296 break; 5297 5298 case DCB_CONDITION_TCP_PORT: 5299 case DCB_CONDITION_TCP_OR_UDP_PORT://Fall through 5300 if(TCP_PORT_ISCSI == p_classif_elem->condition_field) 5301 { 5302 SET_FLAGS(p_classif_elem->flags, DCB_CLASSIF_ENFORCED_BY_VBD); 5303 } 5304 break; 5305 5306 case DCB_CONDITION_ETHERTYPE: 5307 if(ETH_TYPE_FCOE == p_classif_elem->condition_field) 5308 { 5309 SET_FLAGS(p_classif_elem->flags, DCB_CLASSIF_ENFORCED_BY_VBD); 5310 } 5311 break; 5312 5313 case DCB_CONDITION_RESERVED: 5314 case DCB_CONDITION_UDP_PORT://Fall through 5315 case DCB_CONDITION_NETDIRECT_PORT://Fall through 5316 //Not supported by VBD 5317 break; 5318 case DCB_CONDITION_MAX: 5319 default: 5320 DbgBreakMsg("lm_dcbx_runtime_params_updated_en_classif_entries: illegal entry "); 5321 break; 5322 } 5323 } 5324 return lm_status; 5325 } 5326 /** 5327 * @description 5328 * The function will allocate room for the calcification entries 5329 * copy the miniport buffer + local MIB. 5330 * The function will also copy all valid entries to the 5331 * beggining classif_params_copy->classif_table 5332 * @param pdev 5333 * @param classif_params 5334 * @param classif_params_copy 5335 * @param lm_cli_idx 5336 * 5337 * @return STATIC lm_status_t 5338 */ 5339 STATIC lm_status_t 5340 lm_dcbx_ie_copy_alloc_classif_buffer( 5341 INOUT lm_device_t *pdev, 5342 IN const dcb_classif_params_t *classif_params, 5343 OUT dcb_classif_params_t *classif_params_copy, 5344 IN const u8_t lm_cli_idx 5345 ) 5346 { 5347 dcb_classif_elem_t *p_classif_elem = NULL; 5348 lm_status_t lm_status = LM_STATUS_SUCCESS; 5349 u8_t i = 0; 5350 5351 DbgBreakIf(lm_cli_idx != pdev->dcbx_info.indicate_event.lm_cli_idx); 5352 5353 5354 if(classif_params->num_classif_elements) 5355 { 5356 // The total size allocated 5357 classif_params_copy->classif_table = 5358 mm_rt_alloc_mem(pdev, 5359 LM_DCBX_IE_CLASSIF_ENTRIES_TO_ALOC_SIZE(classif_params->num_classif_elements), 5360 pdev->dcbx_info.indicate_event.lm_cli_idx); 5361 5362 if(CHK_NULL(classif_params_copy->classif_table)) 5363 { 5364 DbgBreakMsg(" lm_dcbx_ie_copy_alloc_classif_buffer allocation failure "); 5365 return LM_STATUS_RESOURCE; 5366 } 5367 5368 classif_params_copy->num_classif_elements = classif_params->num_classif_elements; 5369 5370 mm_memcpy(classif_params_copy->classif_table, 5371 classif_params->classif_table, 5372 LM_DCBX_IE_CLASSIF_ENTRIES_TO_ALOC_SIZE(classif_params_copy->num_classif_elements)); 5373 5374 p_classif_elem = (dcb_classif_elem_t *)classif_params_copy->classif_table; 5375 //Clear all the DCB_CLASSIF_ENFORCED_BY_VBD from copy entries 5376 for(i = 0; i < classif_params_copy->num_classif_elements; i++,p_classif_elem++) 5377 { 5378 RESET_FLAGS(p_classif_elem->flags, DCB_CLASSIF_ENFORCED_BY_VBD); 5379 } 5380 } 5381 5382 return lm_status; 5383 } 5384 /** 5385 * Copy dcb parameters given by OS. 5386 * @param pdev 5387 * @param dcb_params 5388 * @param dcb_params_copy 5389 * @param lm_cli_idx 5390 * 5391 * @return STATIC lm_status_t 5392 */ 5393 STATIC lm_status_t 5394 lm_dcbx_ie_params_updated_copy_dcb_params( 5395 INOUT lm_device_t *pdev, 5396 IN dcb_indicate_event_params_t *dcb_params, 5397 OUT dcb_indicate_event_params_t *dcb_params_copy, 5398 IN const u8_t lm_cli_idx) 5399 { 5400 lm_status_t lm_status = LM_STATUS_SUCCESS; 5401 5402 mm_memcpy(dcb_params_copy, 5403 dcb_params, 5404 sizeof(dcb_indicate_event_params_t)); 5405 5406 // miniport pointers should not be used we will realloc a struct in lm_dcbx_ie_copy_alloc_classif_buffer 5407 dcb_params_copy->classif_params.classif_table = NULL; 5408 dcb_params_copy->classif_params.num_classif_elements = 0; 5409 5410 lm_status = lm_dcbx_ie_copy_alloc_classif_buffer(pdev, 5411 &dcb_params->classif_params, 5412 &(dcb_params_copy->classif_params), 5413 lm_cli_idx); 5414 5415 if(LM_STATUS_SUCCESS != lm_status) 5416 { 5417 return lm_status; 5418 } 5419 5420 return lm_status; 5421 } 5422 /** 5423 * @description 5424 * Validate the ETS and PFC parameters that were received can be 5425 * configured. The parameters will later be configured in WI. 5426 * For classification entries that will be supported are 5427 * returned with the flag DCB_CLASSIF_ENFORCED_BY_VBD set. 5428 * @param pdev 5429 * @param dcb_params 5430 * 5431 * @return lm_status_t 5432 */ 5433 lm_status_t 5434 lm_dcbx_ie_params_updated_validate( 5435 INOUT struct _lm_device_t *pdev, 5436 OUT dcb_indicate_event_params_t *dcb_params, 5437 OUT dcb_indicate_event_params_t *dcb_params_copy, 5438 IN const u8_t lm_cli_idx) 5439 { 5440 lm_dcbx_indicate_event_t *indicate_event = &pdev->dcbx_info.indicate_event; 5441 lm_status_t lm_status = LM_STATUS_SUCCESS; 5442 5443 DbgBreakIf(lm_cli_idx != indicate_event->lm_cli_idx); 5444 5445 if((FALSE == pdev->dcbx_info.is_indicate_event_en) || 5446 (IS_MULTI_VNIC(pdev))) 5447 { 5448 DbgBreakMsg("lm_dcbx_runtime_params_updated_validate_pfc called but is_indicate_event_en is false"); 5449 return LM_STATUS_FAILURE; 5450 } 5451 5452 if(GET_FLAGS(dcb_params->flags, DCB_PARAMS_PFC_ENABLED)) 5453 { 5454 lm_status = 5455 lm_dcbx_ie_runtime_params_updated_validate_pfc(pdev, 5456 &dcb_params->pfc_params); 5457 5458 if(LM_STATUS_SUCCESS != lm_status) 5459 { 5460 return lm_status; 5461 } 5462 } 5463 5464 if(GET_FLAGS(dcb_params->flags, DCB_PARAMS_ETS_ENABLED)) 5465 { 5466 lm_status = 5467 lm_dcbx_ie_params_updated_validate_ets(pdev, 5468 &dcb_params->ets_params); 5469 5470 if(LM_STATUS_SUCCESS != lm_status) 5471 { 5472 return lm_status; 5473 } 5474 } 5475 5476 if(GET_FLAGS(dcb_params->flags, DCB_PARAMS_CLASSIF_ENABLED)) 5477 { 5478 lm_status = 5479 lm_dcbx_ie_classif_entries_validate_and_set_enforced(pdev, 5480 &dcb_params->classif_params); 5481 5482 if(LM_STATUS_SUCCESS != lm_status) 5483 { 5484 return lm_status; 5485 } 5486 } 5487 5488 lm_status = lm_dcbx_ie_params_updated_copy_dcb_params(pdev, 5489 dcb_params, 5490 dcb_params_copy, 5491 indicate_event->lm_cli_idx); 5492 if(LM_STATUS_SUCCESS != lm_status) 5493 { 5494 return lm_status; 5495 } 5496 5497 return lm_status; 5498 } 5499 /** 5500 * @description 5501 * Update the local copy of the configuration parameters free 5502 * the old buffer of the classification. 5503 * @param pdev 5504 * @param dcb_params 5505 * @param lm_cli_idx 5506 * 5507 * @return u8_t 5508 */ 5509 STATIC void 5510 lm_dcbx_ie_update_local_params( 5511 INOUT struct _lm_device_t *pdev, 5512 INOUT dcb_indicate_event_params_t *dcb_params, 5513 OUT u8_t *is_local_ets_change, 5514 IN const u8_t lm_cli_idx, 5515 IN u8_t is_ets_admin_updated 5516 ) 5517 { 5518 lm_dcbx_indicate_event_t *indicate_event = &pdev->dcbx_info.indicate_event; 5519 dcb_ets_tsa_param_t ets_params_cmp = {0}; 5520 // I do not want to look at changed in this 5521 const u32_t interesting_flags = DCB_PARAMS_WILLING | DCB_PARAMS_ETS_ENABLED | 5522 DCB_PARAMS_PFC_ENABLED | DCB_PARAMS_CLASSIF_ENABLED; 5523 5524 DbgBreakIf(lm_cli_idx != indicate_event->lm_cli_idx); 5525 5526 // Must be reset each OS configuration 5527 indicate_event->is_ets_ieee_params_os_valid = FALSE; 5528 5529 // Copy before overwriting 5530 mm_memcpy(&(ets_params_cmp), 5531 &(indicate_event->ets_ieee_params_os), 5532 sizeof(ets_params_cmp)); 5533 5534 5535 if(GET_FLAGS(dcb_params->flags, DCB_PARAMS_ETS_ENABLED)) 5536 { 5537 DbgBreakIf(FALSE == is_ets_admin_updated); 5538 5539 mm_memcpy(&(indicate_event->ets_ieee_params_os), 5540 &(dcb_params->ets_params), 5541 sizeof(indicate_event->ets_ieee_params_os)); 5542 5543 if(is_ets_admin_updated) 5544 { 5545 indicate_event->is_ets_ieee_params_os_valid = TRUE; 5546 } 5547 } 5548 else 5549 { 5550 mm_mem_zero(&(indicate_event->ets_ieee_params_os), 5551 sizeof(indicate_event->ets_ieee_params_os)); 5552 } 5553 5554 if(FALSE == mm_memcmp(&(indicate_event->ets_ieee_params_os), 5555 &(ets_params_cmp), 5556 sizeof(ets_params_cmp))) 5557 { 5558 *is_local_ets_change = TRUE; 5559 } 5560 5561 5562 //A final OID_QOS_PARAMETERS with *only* the NDIS_QOS_PARAMETERS_WILLING flag set is sent to an NDIS QOS capable miniport when: 5563 // 1. DCB feature is uninstalled or the msdcb.sys driver is being stopped by the admin. 5564 // 2. The miniport is being unbound by NDIS for whatever reason. 5565 if(DCB_PARAMS_WILLING == GET_FLAGS(dcb_params->flags, interesting_flags)) 5566 { 5567 indicate_event->ets_config_state = lm_dcbx_ets_config_state_cee; 5568 } 5569 else 5570 { 5571 indicate_event->ets_config_state = lm_dcbx_ets_config_state_ieee; 5572 } 5573 } 5574 /** 5575 * For debugging purpose only. 5576 * @param pdev 5577 * @param dcb_params 5578 * @param is_local_ets_change 5579 * @param lm_cli_idx 5580 * 5581 * @return STATIC void 5582 */ 5583 STATIC void 5584 lm_dcbx_ie_dbg_copy_dcb_params( 5585 INOUT struct _lm_device_t *pdev, 5586 INOUT dcb_indicate_event_params_t *dcb_params, 5587 IN const u8_t lm_cli_idx) 5588 { 5589 dcb_indicate_event_params_t *dcb_params_dbg = &pdev->dcbx_info.indicate_event.dcb_params_given_dbg; 5590 const u32_t table_alloc_size_dbg = 5591 min(LM_DCBX_IE_CLASSIF_TABLE_ALOC_SIZE_DBG, 5592 LM_DCBX_IE_CLASSIF_ENTRIES_TO_ALOC_SIZE(dcb_params->classif_params.num_classif_elements)); 5593 5594 dcb_params_dbg->flags = dcb_params->flags; 5595 5596 mm_memcpy(&dcb_params_dbg->ets_params, 5597 &dcb_params->ets_params, 5598 sizeof(dcb_params_dbg->ets_params)); 5599 5600 mm_memcpy(&dcb_params_dbg->pfc_params, 5601 &dcb_params->pfc_params, 5602 sizeof(dcb_params_dbg->pfc_params)); 5603 5604 dcb_params_dbg->classif_params.classif_version = 5605 dcb_params->classif_params.classif_version; 5606 5607 // This can be equal or more than the classification 5608 // entries allocated by dbg and isn't used 5609 dcb_params_dbg->classif_params.num_classif_elements = 5610 dcb_params->classif_params.num_classif_elements; 5611 5612 mm_mem_zero(dcb_params_dbg->classif_params.classif_table, 5613 LM_DCBX_IE_CLASSIF_TABLE_ALOC_SIZE_DBG); 5614 5615 if(NULL != dcb_params_dbg->classif_params.classif_table) 5616 { 5617 mm_memcpy(dcb_params_dbg->classif_params.classif_table, 5618 dcb_params->classif_params.classif_table, 5619 table_alloc_size_dbg); 5620 } 5621 } 5622 5623 /** 5624 * @description 5625 * Creat the IEEE PFC settings from CEE PFC settings. 5626 * @param pdev 5627 * @param cee_pfc 5628 * @param ieee_pfc 5629 * @param flags 5630 * 5631 * @return STATIC void 5632 */ 5633 STATIC void 5634 lm_dcbx_ie_pfc_cee_to_ieee_imp( 5635 INOUT lm_device_t *pdev, 5636 OUT dcb_pfc_param_t *ieee_pfc, 5637 OUT u32_t *flags, 5638 IN const u8_t is_pfc_en, 5639 IN const u8_t pri_en_bitmap 5640 ) 5641 { 5642 SET_FLAGS(*flags, DCB_PARAMS_PFC_ENABLED); 5643 5644 if(0 == is_pfc_en) 5645 { 5646 return; 5647 } 5648 5649 ieee_pfc->pfc_enable = pri_en_bitmap; 5650 } 5651 /** 5652 * @description 5653 * Creat the IEEE PFC settings from CEE PFC settings. 5654 * @param pdev 5655 * @param cee_pfc 5656 * @param ieee_pfc 5657 * @param flags 5658 * 5659 * @return STATIC void 5660 */ 5661 STATIC void 5662 lm_dcbx_ie_pfc_cee_to_ieee( 5663 INOUT lm_device_t *pdev, 5664 IN const dcbx_pfc_feature_t *cee_pfc, 5665 OUT dcb_pfc_param_t *ieee_pfc, 5666 OUT u32_t *flags, 5667 IN const lm_event_code_t event 5668 ) 5669 { 5670 if( LM_EVENT_CODE_DCBX_OPERA_CHANGE == event) 5671 { 5672 lm_dcbx_ie_pfc_cee_to_ieee_imp(pdev, 5673 ieee_pfc, 5674 flags, 5675 (u8_t)pdev->params.dcbx_port_params.pfc.enabled, 5676 LM_DCBX_PFC_PRI_PAUSE_MASK(pdev)); 5677 } 5678 else 5679 { 5680 DbgBreakIf( LM_EVENT_CODE_DCBX_REMOTE_CHANGE != event); 5681 5682 lm_dcbx_ie_pfc_cee_to_ieee_imp(pdev, 5683 ieee_pfc, 5684 flags, 5685 cee_pfc->enabled, 5686 cee_pfc->pri_en_bitmap); 5687 } 5688 } 5689 /** 5690 * @description 5691 * Straight forward parsing. 5692 * The data given from the remote doesn't promise continues 5693 * entries and that for TC_x x is smaller than max TC 5694 * given. 5695 * Strict entry will always be the first TC_0. 5696 * Find an empty cell for strict and count the number of TC 5697 * entries used. 5698 * @param pdev 5699 * @param cee_ets 5700 * @param ieee_ets 5701 * @param flags 5702 * @param event 5703 * 5704 * @return STATIC void 5705 */ 5706 STATIC void 5707 lm_dcbx_ie_ets_cee_to_ieee_unparse( 5708 INOUT lm_device_t *pdev, 5709 IN const dcbx_ets_feature_t *cee_ets, 5710 OUT dcb_ets_tsa_param_t *ieee_ets, 5711 OUT u32_t *flags 5712 ) 5713 { 5714 u8_t pri = 0; 5715 u8_t b_found_strict = FALSE; 5716 u8_t tc_entry = 0; 5717 u8_t tc_entry_bitmap = 0; 5718 u8_t tc_used_bitmap_bw = 0; 5719 u8_t num_of_tc_used = 0; 5720 u8_t strict_tc = 0; 5721 5722 ASSERT_STATIC(DCBX_MAX_NUM_PRI_PG_ENTRIES == DCBX_MAX_NUM_PG_BW_ENTRIES); 5723 ASSERT_STATIC(DCBX_MAX_NUM_PRI_PG_ENTRIES == ARRSIZE(ieee_ets->priority_assignment_table)); 5724 ASSERT_STATIC(DCBX_MAX_NUM_PG_BW_ENTRIES == ARRSIZE(ieee_ets->tc_bw_assignment_table)); 5725 ASSERT_STATIC(DCBX_MAX_NUM_PG_BW_ENTRIES == ARRSIZE(ieee_ets->tsa_assignment_table)); 5726 5727 mm_mem_zero(ieee_ets, sizeof(dcb_ets_tsa_param_t)); 5728 RESET_FLAGS(*flags, DCB_PARAMS_ETS_ENABLED); 5729 5730 if(FALSE == cee_ets->enabled) 5731 { 5732 return; 5733 } 5734 5735 /************ Find an empty cell for strict and count the number of TC entries used*******/ 5736 5737 // Map all BW TC to a bitfield and find if there is a strict TC 5738 for (pri = 0; pri < DCBX_MAX_NUM_PRI_PG_ENTRIES; pri++) 5739 { 5740 tc_entry = DCBX_PRI_PG_GET(cee_ets->pri_pg_tbl, pri); 5741 5742 if(tc_entry < DCBX_MAX_NUM_PG_BW_ENTRIES) 5743 { 5744 // BW 5745 tc_entry_bitmap = (1 << tc_entry); 5746 // Count the number of TC entries given and fill the appropriate COS entry 5747 if (0 == (tc_used_bitmap_bw & tc_entry_bitmap)) 5748 { 5749 // New TC add it to the bitmask 5750 tc_used_bitmap_bw |= tc_entry_bitmap; 5751 num_of_tc_used++; 5752 } 5753 } 5754 else if(DCBX_STRICT_PRI_PG == tc_entry) 5755 { 5756 // Strict 5757 b_found_strict = TRUE; 5758 } 5759 else 5760 { 5761 DbgBreakMsg("lm_dcbx_runtime_params_updated_validate_ets a tc_entry can't be larger" 5762 "than the number of TC supported"); 5763 return; 5764 } 5765 } 5766 5767 // Find an empty cell for strict 5768 if(TRUE == b_found_strict) 5769 { 5770 if((DCBX_MAX_NUM_PRI_PG_ENTRIES) != num_of_tc_used ) 5771 { 5772 // Find a free TC for strict priority 5773 for (tc_entry = 0; tc_entry < DCBX_MAX_NUM_PRI_PG_ENTRIES; tc_entry++) 5774 { 5775 tc_entry_bitmap = (1 << tc_entry); 5776 5777 // Found an unused cell that will be used for strict 5778 if( 0 == (tc_used_bitmap_bw & tc_entry_bitmap)) 5779 { 5780 num_of_tc_used++; 5781 strict_tc = tc_entry; 5782 break; 5783 } 5784 } 5785 } 5786 else 5787 { 5788 DbgBreakMsg("lm_dcbx_ie_ets_cee_to_ieee_unparse: this is a bug we cant have 9 TC"); 5789 // In case we have 8 used TC and strict The last TC will be shared 5790 // between BW and streict. 5791 strict_tc = DCBX_MAX_NUM_PRI_PG_ENTRIES -1; 5792 } 5793 } 5794 5795 for (pri = 0; pri < DCBX_MAX_NUM_PRI_PG_ENTRIES; pri++) 5796 { 5797 tc_entry = DCBX_PRI_PG_GET(cee_ets->pri_pg_tbl, pri); 5798 5799 if(tc_entry < DCBX_MAX_NUM_PG_BW_ENTRIES) 5800 { 5801 // BW 5802 ieee_ets->priority_assignment_table[pri] = tc_entry; 5803 ieee_ets->tsa_assignment_table[tc_entry] = TSA_ASSIGNMENT_DCB_TSA_ETS; 5804 ieee_ets->tc_bw_assignment_table[tc_entry] = DCBX_PG_BW_GET(cee_ets->pg_bw_tbl,tc_entry); 5805 } 5806 else if(DCBX_STRICT_PRI_PG == tc_entry) 5807 { 5808 // Strict 5809 ieee_ets->priority_assignment_table[pri] = strict_tc; 5810 ieee_ets->tsa_assignment_table[strict_tc] = TSA_ASSIGNMENT_DCB_TSA_STRICT; 5811 ieee_ets->tc_bw_assignment_table[strict_tc] = 0; 5812 } 5813 else 5814 { 5815 DbgBreakMsg("lm_dcbx_runtime_params_updated_validate_ets a tc_entry can't be larger" 5816 "than the number of TC supported"); 5817 return; 5818 } 5819 } 5820 5821 ieee_ets->num_traffic_classes = num_of_tc_used; 5822 5823 SET_FLAGS(*flags, DCB_PARAMS_ETS_ENABLED); 5824 } 5825 /** 5826 * @description 5827 * The ETS data is already parse and configured to chip. The use 5828 * of the parse struct is a must because there is an algorithm 5829 * that decide how to configure the chip, and the parsing isn't 5830 * straight forward. 5831 * @param pdev 5832 * @param cee_ets 5833 * @param ieee_ets 5834 * @param flags 5835 * @param event 5836 * 5837 * @return STATIC void 5838 */ 5839 STATIC void 5840 lm_dcbx_ie_ets_cee_to_ieee_parsed_data( 5841 INOUT lm_device_t *pdev, 5842 OUT dcb_ets_tsa_param_t *ieee_ets, 5843 OUT u32_t *flags 5844 ) 5845 { 5846 u8_t i = 0; 5847 u8_t tc_assign = 0; 5848 const u8_t max_tc_sup = lm_dcbx_cos_max_num(pdev) ; 5849 pg_params_t *ets = &(pdev->params.dcbx_port_params.ets); 5850 u16_t pri_bit = 0; 5851 5852 ASSERT_STATIC(DCBX_MAX_NUM_PRI_PG_ENTRIES == DCBX_MAX_NUM_PG_BW_ENTRIES); 5853 ASSERT_STATIC(DCBX_MAX_NUM_PRI_PG_ENTRIES == ARRSIZE(ieee_ets->priority_assignment_table)); 5854 ASSERT_STATIC(DCBX_MAX_NUM_PG_BW_ENTRIES == ARRSIZE(ieee_ets->tc_bw_assignment_table)); 5855 ASSERT_STATIC(DCBX_MAX_NUM_PG_BW_ENTRIES == ARRSIZE(ieee_ets->tsa_assignment_table)); 5856 5857 SET_FLAGS(*flags, DCB_PARAMS_ETS_ENABLED); 5858 5859 if((FALSE == ets->enabled) || 5860 (max_tc_sup < ets->num_of_cos)) 5861 { 5862 DbgBreakIf(max_tc_sup < ets->num_of_cos); 5863 return; 5864 } 5865 5866 ieee_ets->num_traffic_classes = ets->num_of_cos; 5867 5868 for(i = 0; i < ARRSIZE(ieee_ets->priority_assignment_table) ; i++) 5869 { 5870 pri_bit = 1 << i; 5871 for(tc_assign = 0 ; tc_assign < ets->num_of_cos; tc_assign++) 5872 { 5873 if(0 != (pri_bit & ets->cos_params[tc_assign].pri_bitmask)) 5874 { 5875 break; 5876 } 5877 } 5878 5879 // If the priority doesn't belong to non of the cos_params then 5880 // assign this priority to zero. 5881 if(ets->num_of_cos == tc_assign) 5882 { 5883 tc_assign = 0; 5884 } 5885 5886 ieee_ets->priority_assignment_table[i] = tc_assign; 5887 } 5888 5889 for(tc_assign = 0 ; tc_assign < ets->num_of_cos; tc_assign++) 5890 { 5891 if(DCBX_S_PRI_INVALID != ets->cos_params[tc_assign].s_pri) 5892 {// COS is SP 5893 // Strict 5894 DbgBreakIf(DCBX_INVALID_COS_BW != ets->cos_params[tc_assign].bw_tbl); 5895 5896 ieee_ets->tsa_assignment_table[tc_assign] = TSA_ASSIGNMENT_DCB_TSA_STRICT; 5897 ieee_ets->tc_bw_assignment_table[tc_assign] = 0; 5898 } 5899 else 5900 {// COS is BW 5901 DbgBreakIf(DCBX_INVALID_COS_BW == ets->cos_params[tc_assign].bw_tbl); 5902 5903 ieee_ets->tsa_assignment_table[tc_assign] = TSA_ASSIGNMENT_DCB_TSA_ETS; 5904 ieee_ets->tc_bw_assignment_table[tc_assign] = (u8_t)ets->cos_params[tc_assign].bw_tbl; 5905 } 5906 } 5907 } 5908 /** 5909 * @description 5910 * Creat the IEEE ETS settings from CEE ETS settings. 5911 * @param pdev 5912 * @param cee_ets 5913 * @param ieee_ets 5914 * @param flags 5915 * 5916 * @return STATIC void 5917 */ 5918 STATIC void 5919 lm_dcbx_ie_ets_cee_to_ieee( 5920 INOUT lm_device_t *pdev, 5921 IN const dcbx_ets_feature_t *cee_ets, 5922 OUT dcb_ets_tsa_param_t *ieee_ets, 5923 OUT u32_t *flags, 5924 IN const lm_event_code_t event 5925 ) 5926 { 5927 if( LM_EVENT_CODE_DCBX_OPERA_CHANGE == event) 5928 { 5929 lm_dcbx_ie_ets_cee_to_ieee_parsed_data(pdev, ieee_ets, flags); 5930 } 5931 else 5932 { 5933 DbgBreakIf( LM_EVENT_CODE_DCBX_REMOTE_CHANGE != event); 5934 lm_dcbx_ie_ets_cee_to_ieee_unparse(pdev, 5935 cee_ets, 5936 ieee_ets, 5937 flags); 5938 } 5939 } 5940 /** 5941 * Update the classification entry with the data given. 5942 * 5943 * @param pdev 5944 * @param classif_entry 5945 * @param condition_selector 5946 * @param condition_field 5947 * @param pri 5948 * 5949 * @return STATIC void 5950 */ 5951 STATIC void 5952 lm_dcbx_ie_classif_set_entry( 5953 IN lm_device_t *pdev, 5954 IN dcb_classif_elem_t *classif_entry, 5955 IN dcb_condition_selector_t condition_selector, 5956 IN u16_t condition_field, 5957 IN u16_t pri) 5958 { 5959 classif_entry->flags = 0; 5960 classif_entry->condition_selector = condition_selector; 5961 classif_entry->condition_field = condition_field; 5962 classif_entry->action_selector = DCB_ACTION_PRIORITY; 5963 classif_entry->action_field = pri; 5964 } 5965 /** 5966 * This default entry must be the first one. 5967 * @param pdev 5968 * @param cee_classif 5969 * @param classif_entry 5970 * 5971 * @return STATIC u8_t return the number of entries used by the 5972 * function. 5973 */ 5974 STATIC void 5975 lm_dcbx_ie_classif_add_default( 5976 INOUT lm_device_t *pdev, 5977 IN const dcbx_app_priority_feature_t *cee_classif, 5978 IN dcb_classif_elem_t *classif_entry) 5979 { 5980 u16_t const default_pri = (cee_classif->default_pri < MAX_PFC_PRIORITIES)? cee_classif->default_pri: 0; 5981 5982 lm_dcbx_ie_classif_set_entry( pdev, 5983 classif_entry, 5984 DCB_CONDITION_DEFAULT, 5985 0, 5986 default_pri); 5987 } 5988 /** 5989 * Parse the CEE entries to indicate event classification 5990 * entries. 5991 * @param pdev 5992 * @param cee_app_pri_tbl 5993 * @param cee_app_pri_tbl_size 5994 * @param classif_table 5995 * @param is_iscsi_cee_rec - There is an ISCSI CEE entry. 5996 * @param event 5997 * 5998 * @return STATIC u8_t return the number of entries used by the 5999 * function. 6000 */ 6001 STATIC u8_t 6002 lm_dcbx_ie_classif_parse_cee_arrray( 6003 INOUT lm_device_t *pdev, 6004 IN const dcbx_app_priority_entry_t *cee_app_pri_tbl, 6005 IN const u8_t cee_app_pri_tbl_size, 6006 INOUT dcb_classif_elem_t *classif_table, 6007 OUT u8_t *is_iscsi_cee_rec 6008 ) 6009 { 6010 u8_t cee_index = 0; 6011 u32_t pri = 0; 6012 dcb_condition_selector_t condition_selector = 0; 6013 u8_t num_entry_used = 0; 6014 u8_t dummy_flag = FALSE; 6015 6016 if(CHK_NULL(cee_app_pri_tbl)) 6017 { 6018 return 0; 6019 } 6020 6021 for( cee_index = 0; 6022 (cee_index < cee_app_pri_tbl_size); 6023 cee_index++) 6024 { 6025 pri = MAX_PFC_PRIORITIES; 6026 6027 if(0 == GET_FLAGS(cee_app_pri_tbl[cee_index].appBitfield, DCBX_APP_ENTRY_VALID)) 6028 { 6029 continue; 6030 } 6031 6032 /********************************************************************/ 6033 /******** start parse entry to from CEE format to IEEE format********/ 6034 if(GET_FLAGS(cee_app_pri_tbl[cee_index].appBitfield, DCBX_APP_SF_ETH_TYPE)) 6035 { 6036 condition_selector = DCB_CONDITION_ETHERTYPE; 6037 } 6038 else if(GET_FLAGS(cee_app_pri_tbl[cee_index].appBitfield, DCBX_APP_SF_PORT)) 6039 { 6040 condition_selector = DCB_CONDITION_TCP_OR_UDP_PORT; 6041 } 6042 else 6043 { 6044 DbgBreakMsg("lm_dcbx_classif_cee_to_ieee invalid appBitfield "); 6045 continue; 6046 } 6047 6048 lm_dcbx_get_ap_priority(pdev, &pri, cee_app_pri_tbl[cee_index].pri_bitmap, &dummy_flag); 6049 6050 if(MAX_PFC_PRIORITIES == pri) 6051 { 6052 if(0 == cee_app_pri_tbl[cee_index].pri_bitmap) 6053 { 6054 // This is a patch: 6055 // We don't assert as a request from DVT:(CQ64888 and CQ59423). 6056 // A quote from Darshan (DVT) mail "Brocade expects (just like Navasota) that PFC 6057 // be enabled on the iSCSI traffic class (which, I agree, is inappropriate). If the PFC is not set on the iSCSI 6058 // traffic class then it sends the iSCSI App TLV with PRI bit map of zero irrespective of whatever PRI you have 6059 // configured for iSCSI. Once PFC is enabled, it sends the correct App TLV bit map." 6060 #if defined(DBG) 6061 DbgMessage(pdev, FATAL, "lm_dcbx_ie_classif_parse_cee_arrray invalid pri for valid entry "); 6062 #else 6063 DbgBreakMsg("lm_dcbx_ie_classif_parse_cee_arrray invalid pri for valid entry "); 6064 #endif 6065 } 6066 else 6067 { 6068 DbgBreakMsg("lm_dcbx_ie_classif_parse_cee_arrray invalid pri for valid entry "); 6069 } 6070 continue; 6071 } 6072 6073 lm_dcbx_ie_classif_set_entry( pdev, 6074 &(classif_table[num_entry_used]), 6075 condition_selector, 6076 cee_app_pri_tbl[cee_index].app_id, 6077 (u16_t)pri); 6078 6079 num_entry_used++; 6080 6081 // ISCSI is a special case until we will implement IEEE we can send DCB_CONDITION_TCP_PORT. 6082 if((DCB_CONDITION_TCP_OR_UDP_PORT == condition_selector) && 6083 (TCP_PORT_ISCSI == cee_app_pri_tbl[cee_index].app_id)) 6084 { 6085 (*is_iscsi_cee_rec) = TRUE; 6086 } 6087 } 6088 6089 return num_entry_used; 6090 } 6091 /** 6092 * This function is only for verifying that the classification 6093 * Parameters sent to OS are coherent with local classification 6094 * parameters and that the parameters are generally coherent 6095 * 6096 * @param pdev 6097 * @param ieee_classif 6098 * @param event 6099 * 6100 * @return STATIC void 6101 */ 6102 STATIC void 6103 lm_dcbx_ie_classif_cee_to_ieee_check_param_dbg( 6104 IN const lm_device_t *pdev, 6105 IN const dcb_classif_params_t *ieee_classif, 6106 IN const lm_event_code_t event 6107 ) 6108 { 6109 dcb_classif_elem_t *p_classif_elem = ieee_classif->classif_table; 6110 u8_t i = 0; 6111 lm_dcbx_ie_classif_dbg_t classif_dbg[MAX_TRAFFIC_TYPE] = {{0}}; 6112 6113 for(i = 0; i < ieee_classif->num_classif_elements; i++) 6114 { 6115 if(DCB_ACTION_PRIORITY != p_classif_elem[i].action_selector) 6116 { 6117 // VBD only supports condition_selector that is based on priority 6118 continue; 6119 } 6120 6121 switch(p_classif_elem[i].condition_selector) 6122 { 6123 case DCB_CONDITION_DEFAULT: 6124 // Must be the first entry 6125 DbgBreakIf(0 != i); 6126 break; 6127 6128 case DCB_CONDITION_TCP_PORT: 6129 case DCB_CONDITION_TCP_OR_UDP_PORT://Fall through 6130 if(TCP_PORT_ISCSI == p_classif_elem[i].condition_field) 6131 { 6132 classif_dbg[LLFC_TRAFFIC_TYPE_ISCSI].pri = p_classif_elem[i].action_field; 6133 classif_dbg[LLFC_TRAFFIC_TYPE_ISCSI].num_entries++; 6134 } 6135 break; 6136 6137 case DCB_CONDITION_ETHERTYPE: 6138 if(ETH_TYPE_FCOE == p_classif_elem[i].condition_field) 6139 { 6140 classif_dbg[LLFC_TRAFFIC_TYPE_FCOE].pri = p_classif_elem[i].action_field; 6141 classif_dbg[LLFC_TRAFFIC_TYPE_FCOE].num_entries++; 6142 } 6143 break; 6144 6145 case DCB_CONDITION_RESERVED: 6146 case DCB_CONDITION_UDP_PORT://Fall through 6147 case DCB_CONDITION_NETDIRECT_PORT://Fall through 6148 //Not supported by VBD 6149 break; 6150 case DCB_CONDITION_MAX: 6151 default: 6152 DbgBreakMsg("lm_dcbx_runtime_params_updated_en_classif_entries: illegal entry "); 6153 break; 6154 } 6155 } 6156 6157 // traffic_type_priority and classification DCBX_OPERA parameters are derived both from local MIB 6158 if( LM_EVENT_CODE_DCBX_OPERA_CHANGE == event) 6159 { 6160 for(i = 0; i < MAX_TRAFFIC_TYPE; i++) 6161 { 6162 //num_entries is more interesting if num_entries =< 1 ,otherwise this is a unusually configuration. 6163 if(1 == classif_dbg[i].num_entries) 6164 { 6165 DbgBreakIf(classif_dbg[i].pri != 6166 pdev->params.dcbx_port_params.app.traffic_type_priority[i]); 6167 } 6168 } 6169 } 6170 6171 } 6172 /** 6173 * @description 6174 * Creat the IEEE settings from CEE settings. 6175 * If there is a given_tabel copy it to the beggining of the 6176 * ieee_classif. 6177 * After search the CEE (local /remote) entries (read from 6178 * chip)an add any valid CEE entry because it has a higher 6179 * priority than given_tabel. 6180 * @param pdev 6181 * @param cee_classif 6182 * @param ieee_classif 6183 * @param ieee_classif_alloc_size 6184 * @param given_tabel 6185 * @param given_tabel_alloc_size 6186 * @param flags 6187 * 6188 * @return STATIC void 6189 */ 6190 STATIC lm_status_t 6191 lm_dcbx_ie_classif_cee_to_ieee( 6192 INOUT lm_device_t *pdev, 6193 IN const dcbx_app_priority_feature_t *cee_classif, 6194 IN const dcbx_app_priority_entry_t *cee_app_tbl_ext, 6195 IN const u8_t cee_app_tbl_ext_size, 6196 OUT dcb_classif_params_t *ieee_classif, 6197 IN const u32_t ieee_classif_alloc_size, 6198 OUT u32_t *flags, 6199 IN const lm_event_code_t event 6200 ) 6201 { 6202 lm_dcbx_indicate_event_t *indicate_event = &pdev->dcbx_info.indicate_event; 6203 dcb_classif_elem_t *classif_table = ieee_classif->classif_table; 6204 lm_status_t lm_status = LM_STATUS_SUCCESS; 6205 u16_t num_entry_used = 0; 6206 u8_t is_iscsi_cee_rec = FALSE; 6207 6208 DbgBreakIf(0 != (ieee_classif_alloc_size % sizeof(dcb_classif_elem_t))); 6209 6210 // Check enablement of classification 6211 if( LM_EVENT_CODE_DCBX_OPERA_CHANGE == event) 6212 { 6213 if(0 == pdev->params.dcbx_port_params.app.enabled) 6214 { 6215 return LM_STATUS_SUCCESS; 6216 } 6217 // Default must be the first entry. 6218 lm_dcbx_ie_classif_add_default(pdev, 6219 cee_classif, 6220 classif_table); 6221 num_entry_used++; 6222 } 6223 else 6224 { 6225 DbgBreakIf( LM_EVENT_CODE_DCBX_REMOTE_CHANGE != event); 6226 if(0 == cee_classif->enabled) 6227 { 6228 return LM_STATUS_SUCCESS; 6229 } 6230 } 6231 6232 SET_FLAGS(*flags, DCB_PARAMS_CLASSIF_ENABLED); 6233 6234 num_entry_used += lm_dcbx_ie_classif_parse_cee_arrray( 6235 pdev, 6236 cee_classif->app_pri_tbl, 6237 ARRSIZE(cee_classif->app_pri_tbl), 6238 &(classif_table[num_entry_used]), 6239 &is_iscsi_cee_rec); 6240 6241 num_entry_used += lm_dcbx_ie_classif_parse_cee_arrray( 6242 pdev, 6243 cee_app_tbl_ext, 6244 cee_app_tbl_ext_size, 6245 &(classif_table[num_entry_used]), 6246 &is_iscsi_cee_rec); 6247 6248 // If the operational configuration from MCP contains an entry with 'TCP or UDP port' = 3260 use that entry, 6249 // Else if OS configuration contained an entry with 'TCP port' = 3260 use that entry, 6250 // Else use the default configuration. 6251 if(( LM_EVENT_CODE_DCBX_OPERA_CHANGE == event) && 6252 ( FALSE == is_iscsi_cee_rec) && 6253 ( LM_DCBX_ILLEGAL_PRI != indicate_event->iscsi_tcp_pri)) 6254 { 6255 DbgBreakIf(pdev->params.dcbx_port_params.app.traffic_type_priority[LLFC_TRAFFIC_TYPE_ISCSI] != 6256 indicate_event->iscsi_tcp_pri); 6257 6258 lm_dcbx_ie_classif_set_entry( pdev, 6259 &(classif_table[num_entry_used]), 6260 DCB_CONDITION_TCP_PORT, 6261 TCP_PORT_ISCSI, 6262 indicate_event->iscsi_tcp_pri); 6263 num_entry_used++; 6264 } 6265 6266 ieee_classif->num_classif_elements = num_entry_used; 6267 6268 lm_dcbx_ie_classif_cee_to_ieee_check_param_dbg(pdev, 6269 ieee_classif, 6270 event); 6271 6272 return lm_status; 6273 } 6274 /** 6275 * Check if there is a classification parameter update 6276 * @param pdev 6277 * @param params_prev 6278 * @param params_newest 6279 * 6280 * @return STATIC u8_t 6281 */ 6282 STATIC u8_t 6283 lm_dcbx_ie_classif_check_if_params_changed( 6284 IN const dcb_classif_params_t *params_prev, 6285 IN const dcb_classif_params_t *params_newest) 6286 { 6287 dcb_classif_elem_t *p_classif_prev = params_prev->classif_table; 6288 dcb_classif_elem_t *p_classif_newest = params_newest->classif_table; 6289 u16_t index_prev = 0; 6290 u16_t index_newest = 0; 6291 u8_t is_entry_found = 0; 6292 6293 if(params_prev->num_classif_elements != params_newest->num_classif_elements) 6294 { 6295 return TRUE; 6296 } 6297 6298 for(index_prev = 0 ; index_prev < params_prev->num_classif_elements ; index_prev++) 6299 { 6300 is_entry_found = FALSE; 6301 for(index_newest = 0 ; index_newest < params_prev->num_classif_elements ; index_newest++) 6302 { 6303 if(mm_memcmp(&(p_classif_prev[index_prev]), 6304 &(p_classif_newest[index_newest]), 6305 sizeof(p_classif_prev[index_prev]))) 6306 { 6307 is_entry_found = TRUE; 6308 break; 6309 } 6310 } 6311 6312 if(FALSE == is_entry_found) 6313 { 6314 return TRUE; 6315 } 6316 } 6317 6318 return FALSE; 6319 } 6320 /** 6321 * @description 6322 * Creat the indicate event struct based on data read from chip. 6323 * If the data has change call upper layer indicate event. 6324 * @param pdev 6325 * @param indicate_params 6326 * @param dcbx_features 6327 * @param event 6328 * @param ieee_classif_alloc_size 6329 * @param given_tabel 6330 * @param given_tabel_alloc_size 6331 * @param ets_given 6332 * @param is_ets_change 6333 * @param is_classif_change 6334 * 6335 * @return STATIC lm_status_t 6336 */ 6337 STATIC lm_status_t 6338 lm_dcbx_ie_check_if_param_change_common( 6339 INOUT lm_device_t *pdev, 6340 INOUT dcb_indicate_event_params_t *indicate_params, 6341 IN dcbx_features_t *dcbx_features, 6342 IN const dcbx_app_priority_entry_t *cee_app_tbl_ext, 6343 IN const u8_t cee_app_tbl_ext_size, 6344 IN const lm_event_code_t event, 6345 IN const u32_t ieee_classif_alloc_size, 6346 IN const lm_dcbx_ie_ets_ieee_config_state ets_ieee_config_state, 6347 IN const dcb_ets_tsa_param_t *ets_ieee_config, 6348 IN const u8_t is_ets_change) 6349 { 6350 dcb_indicate_event_params_t indicate_newest_params = {0}; 6351 lm_status_t lm_status = LM_STATUS_SUCCESS; 6352 u8_t is_changed = 0; 6353 6354 // Allocate local buffer that is enough for all entries given and read from chip 6355 indicate_newest_params.classif_params.classif_table = 6356 mm_rt_alloc_mem(pdev, ieee_classif_alloc_size, pdev->dcbx_info.indicate_event.lm_cli_idx); 6357 6358 if(CHK_NULL(indicate_newest_params.classif_params.classif_table)) 6359 { 6360 return LM_STATUS_RESOURCE; 6361 } 6362 mm_mem_zero(indicate_newest_params.classif_params.classif_table, ieee_classif_alloc_size); 6363 6364 lm_dcbx_ie_pfc_cee_to_ieee(pdev, 6365 &dcbx_features->pfc, 6366 &indicate_newest_params.pfc_params, 6367 &indicate_newest_params.flags, 6368 event 6369 ); 6370 6371 if(FALSE == mm_memcmp(&indicate_params->pfc_params, 6372 &indicate_newest_params.pfc_params , 6373 sizeof(dcb_pfc_param_t))) 6374 { 6375 is_changed = TRUE; 6376 SET_FLAGS(indicate_newest_params.flags, DCB_PARAMS_PFC_CHANGED); 6377 } 6378 6379 if(lm_dcbx_ets_ieee_config_not_valid == ets_ieee_config_state) 6380 { 6381 lm_dcbx_ie_ets_cee_to_ieee(pdev, 6382 &dcbx_features->ets, 6383 &indicate_newest_params.ets_params, 6384 &indicate_newest_params.flags, 6385 event 6386 ); 6387 } 6388 else 6389 { 6390 if(lm_dcbx_ets_ieee_config_en == ets_ieee_config_state) 6391 { 6392 SET_FLAGS(indicate_newest_params.flags, DCB_PARAMS_ETS_ENABLED); 6393 // copy the ets_params that were before (ETS params given from upper module) 6394 mm_memcpy(&indicate_newest_params.ets_params, 6395 ets_ieee_config, 6396 sizeof(dcb_ets_tsa_param_t)); 6397 } 6398 else 6399 { 6400 DbgBreakIf(lm_dcbx_ets_ieee_config_di != ets_ieee_config_state); 6401 6402 RESET_FLAGS(indicate_newest_params.flags, DCB_PARAMS_ETS_ENABLED); 6403 mm_mem_zero(&indicate_newest_params.ets_params, 6404 sizeof(dcb_ets_tsa_param_t)); 6405 } 6406 } 6407 6408 if((FALSE == mm_memcmp(&indicate_params->ets_params, 6409 &indicate_newest_params.ets_params , 6410 sizeof(dcb_ets_tsa_param_t))) || 6411 (TRUE == is_ets_change)) 6412 { 6413 is_changed = TRUE; 6414 if(GET_FLAGS(indicate_newest_params.flags, DCB_PARAMS_ETS_ENABLED)) 6415 { 6416 SET_FLAGS(indicate_newest_params.flags, DCB_PARAMS_ETS_CHANGED); 6417 } 6418 } 6419 6420 lm_status = lm_dcbx_ie_classif_cee_to_ieee(pdev, 6421 &dcbx_features->app, 6422 cee_app_tbl_ext, 6423 cee_app_tbl_ext_size, 6424 &indicate_newest_params.classif_params, 6425 ieee_classif_alloc_size, 6426 &indicate_newest_params.flags, 6427 event 6428 ); 6429 6430 DbgBreakIf(LM_STATUS_SUCCESS != lm_status); 6431 6432 if(TRUE == lm_dcbx_ie_classif_check_if_params_changed( 6433 &indicate_params->classif_params, 6434 &indicate_newest_params.classif_params)) 6435 { 6436 is_changed = TRUE; 6437 SET_FLAGS(indicate_newest_params.flags, DCB_PARAMS_CLASSIF_CHANGED); 6438 } 6439 6440 if(TRUE == is_changed) 6441 { 6442 6443 mm_memcpy(&indicate_params->flags, 6444 &indicate_newest_params.flags, 6445 sizeof(indicate_newest_params.flags)); 6446 6447 mm_memcpy(&indicate_params->pfc_params, 6448 &indicate_newest_params.pfc_params, 6449 sizeof(indicate_newest_params.pfc_params)); 6450 6451 mm_memcpy(&indicate_params->ets_params, 6452 &indicate_newest_params.ets_params, 6453 sizeof(indicate_newest_params.ets_params)); 6454 6455 /* Start Update indicate_params with newest temp buffer params */ 6456 mm_memcpy(indicate_params->classif_params.classif_table, 6457 indicate_newest_params.classif_params.classif_table, 6458 ieee_classif_alloc_size); 6459 6460 indicate_params->classif_params.num_classif_elements = indicate_newest_params.classif_params.num_classif_elements; 6461 6462 6463 /* End: Update indicate_params with newest temp buffer params */ 6464 #ifdef _VBD_CMD_ 6465 MM_DCB_INDICATE_EVENT(pdev,event,(u8_t*)indicate_params, sizeof(dcb_indicate_event_params_t)); 6466 #endif 6467 #ifdef _VBD_ 6468 MM_DCB_INDICATE_EVENT(pdev,event,(u8_t*)indicate_params, sizeof(dcb_indicate_event_params_t)); 6469 #endif 6470 } 6471 // Free the local allocated buffer 6472 mm_rt_free_mem(pdev, 6473 indicate_newest_params.classif_params.classif_table, 6474 ieee_classif_alloc_size, 6475 pdev->dcbx_info.indicate_event.lm_cli_idx); 6476 return lm_status; 6477 } 6478 /** 6479 * @description 6480 * Check if local parameter has change , if they have change 6481 * indicate event to upper layer. 6482 * @param pdev 6483 * @param p_local_mib 6484 * @param dcbx_neg_res_offset 6485 * @param is_ets_change 6486 * @param is_classif_change 6487 * 6488 * @return lm_status_t 6489 */ 6490 lm_status_t 6491 lm_dcbx_ie_check_if_param_change_local( 6492 INOUT lm_device_t *pdev, 6493 IN lldp_local_mib_t *p_in_local_mib, 6494 IN lldp_local_mib_ext_t *p_in_local_mib_ext, 6495 IN const u8_t is_ets_change) 6496 { 6497 lm_dcbx_indicate_event_t *indicate_event = &pdev->dcbx_info.indicate_event; 6498 lldp_local_mib_t local_mib = {0}; 6499 lldp_local_mib_ext_t local_mib_ext = {0}; 6500 lm_status_t lm_status = LM_STATUS_SUCCESS; 6501 lldp_local_mib_t *p_local_mib = p_in_local_mib; 6502 lldp_local_mib_ext_t *p_local_mib_ext = p_in_local_mib_ext; 6503 6504 if(NULL == p_local_mib) 6505 { 6506 // Local MIB was not received read local MIB 6507 lm_status = lm_dcbx_read_local_mib_fields(pdev, 6508 &local_mib, 6509 &local_mib_ext); 6510 6511 if(LM_STATUS_SUCCESS != lm_status) 6512 { 6513 return lm_status; 6514 } 6515 6516 p_local_mib = &local_mib; 6517 p_local_mib_ext = &local_mib_ext; 6518 } 6519 6520 if(CHK_NULL(p_local_mib) || CHK_NULL(p_local_mib_ext)) 6521 { 6522 DbgBreakMsg("lm_get_dcbx_drv_param wrong in parameters "); 6523 return lm_status; 6524 } 6525 6526 lm_status = lm_dcbx_ie_check_if_param_change_common( 6527 pdev, 6528 &(indicate_event->local_params), 6529 &p_local_mib->features, 6530 p_local_mib_ext->app_pri_tbl_ext, 6531 ARRSIZE(p_local_mib_ext->app_pri_tbl_ext), 6532 LM_EVENT_CODE_DCBX_OPERA_CHANGE, 6533 LM_DCBX_IE_CLASSIF_TABLE_ALOC_SIZE_LOCAL, 6534 indicate_event->ets_ieee_config_state, 6535 &indicate_event->ets_ieee_params_config, 6536 is_ets_change); 6537 6538 DbgBreakIf(LM_STATUS_SUCCESS != lm_status); 6539 6540 return lm_status; 6541 } 6542 /** 6543 * @description 6544 * Check if Remote parameter has change , if they have change 6545 * indicate event to upper layer. 6546 * @param pdev 6547 * @param dcbx_neg_res_offset 6548 * 6549 * @return lm_status_t 6550 */ 6551 lm_status_t 6552 lm_dcbx_ie_check_if_param_change_remote( 6553 INOUT lm_device_t *pdev) 6554 { 6555 lldp_remote_mib_t remote_mib = {0}; 6556 lm_status_t lm_status = LM_STATUS_SUCCESS; 6557 6558 lm_status = lm_dcbx_read_remote_local_mib(pdev, 6559 (u32_t *)&remote_mib, 6560 DCBX_READ_REMOTE_MIB); 6561 6562 if(LM_STATUS_SUCCESS != lm_status) 6563 { 6564 return lm_status; 6565 } 6566 6567 6568 lm_status = lm_dcbx_ie_check_if_param_change_common( 6569 pdev, 6570 &(pdev->dcbx_info.indicate_event.remote_params), 6571 &remote_mib.features, 6572 NULL, 6573 0, 6574 LM_EVENT_CODE_DCBX_REMOTE_CHANGE, 6575 LM_DCBX_IE_CLASSIF_TABLE_ALOC_SIZE_REMOTE, 6576 lm_dcbx_ets_ieee_config_not_valid, 6577 NULL, 6578 FALSE); 6579 6580 DbgBreakIf(LM_STATUS_SUCCESS != lm_status); 6581 6582 return lm_status; 6583 } 6584 /** 6585 * @description 6586 * This function will check if local or remote parameters have 6587 * changed if the parameters have change the function will 6588 * update upper layer. 6589 * Local parameters can be given : 6590 * 1. If we read local parameters to configure the chip we 6591 * should use the same parameter to update upper layer (although 6592 * if there was a change an interrupt is expected) 2.If we are 6593 * from update parameters flow from upper layer ETS and clasif 6594 * settings are not update to chip so if they change we will 6595 * update function. 6596 * @param pdev 6597 * @param p_local_mib 6598 * @param is_ets_change 6599 * @param is_classif_change 6600 * 6601 * @return lm_status_t 6602 */ 6603 lm_status_t 6604 lm_dcbx_ie_check_if_param_change( 6605 INOUT lm_device_t *pdev, 6606 IN lldp_local_mib_t *p_local_mib, 6607 IN lldp_local_mib_ext_t *p_local_mib_ext, 6608 IN u8_t is_local_ets_change) 6609 { 6610 lm_status_t lm_status = LM_STATUS_SUCCESS; 6611 if(FALSE == pdev->dcbx_info.is_indicate_event_en) 6612 { 6613 DbgBreakMsg("lm_dcbx_runtime_params_updated_validate_pfc called but is_indicate_event_en is false"); 6614 return LM_STATUS_FAILURE; 6615 } 6616 6617 6618 lm_status = lm_dcbx_ie_check_if_param_change_local(pdev, 6619 p_local_mib, 6620 p_local_mib_ext, 6621 is_local_ets_change); 6622 6623 DbgBreakIf(LM_STATUS_SUCCESS != lm_status); 6624 6625 lm_status = lm_dcbx_ie_check_if_param_change_remote(pdev); 6626 6627 6628 DbgBreakIf(LM_STATUS_SUCCESS != lm_status); 6629 6630 return lm_status; 6631 } 6632 /** 6633 * 6634 * 6635 * @author shayh (10/9/2011) 6636 * 6637 * @param pdev 6638 */ 6639 void lm_dcbx_ie_update_bacs_state( 6640 INOUT lm_device_t *pdev, 6641 IN const u32_t flags 6642 ) 6643 { 6644 lm_dcbx_indicate_event_t *indicate_event = &pdev->dcbx_info.indicate_event; 6645 6646 SET_FLAGS(indicate_event->dcb_current_oper_state_bitmap, DCB_STATE_CONFIGURED_BY_OS_QOS); 6647 6648 if(GET_FLAGS(flags, DCB_PARAMS_WILLING)) 6649 { 6650 SET_FLAGS(indicate_event->dcb_current_oper_state_bitmap, 6651 DCB_STATE_CONFIGURED_BY_OS_QOS_TO_WILLING); 6652 } 6653 else 6654 { 6655 RESET_FLAGS(indicate_event->dcb_current_oper_state_bitmap, 6656 DCB_STATE_CONFIGURED_BY_OS_QOS_TO_WILLING); 6657 } 6658 } 6659 /** 6660 * @description 6661 * 1.Update the local copy of the configuration parameters 6662 * 2.Set data to admin parameters (PFC settings classification 6663 * and PFC as willing ETS as not willing ) update MCP. 6664 * 3. If there are ETS or clasification changes to local 6665 * parameters Update HW/FW because MCP is only awre of PFC 6666 * changes (and will give us an interrupt if there are changes). 6667 * @param pdev 6668 * @param dcb_params 6669 * @param lm_cli_idx 6670 * 6671 * @return lm_status_t 6672 */ 6673 lm_status_t 6674 lm_dcbx_ie_runtime_params_updated( 6675 INOUT struct _lm_device_t *pdev, 6676 INOUT dcb_indicate_event_params_t *dcb_params, 6677 IN const u8_t lm_cli_idx) 6678 { 6679 lm_dcbx_indicate_event_t *indicate_event = &pdev->dcbx_info.indicate_event; 6680 lm_status_t lm_status = LM_STATUS_SUCCESS; 6681 u8_t is_local_ets_change = FALSE; 6682 u8_t classif_change_mcp_not_aware = FALSE; 6683 u8_t is_ets_admin_updated = FALSE; 6684 6685 DbgBreakIf(lm_cli_idx != indicate_event->lm_cli_idx); 6686 6687 if(FALSE == pdev->dcbx_info.is_indicate_event_en) 6688 { 6689 DbgBreakMsg("lm_dcbx_runtime_params_updated_validate_pfc called but is_indicate_event_en is false"); 6690 return LM_STATUS_FAILURE; 6691 } 6692 6693 /* Update admin MIB*/ 6694 lm_status = lm_dcbx_ie_admin_mib_updated_runtime(pdev, 6695 dcb_params, 6696 &classif_change_mcp_not_aware, 6697 &is_ets_admin_updated); 6698 6699 if(LM_STATUS_SUCCESS != lm_status) 6700 { 6701 return lm_status; 6702 } 6703 6704 lm_dcbx_ie_update_local_params(pdev, 6705 dcb_params, 6706 &is_local_ets_change, 6707 indicate_event->lm_cli_idx, 6708 is_ets_admin_updated 6709 ); 6710 6711 lm_dcbx_ie_dbg_copy_dcb_params(pdev, 6712 dcb_params, 6713 indicate_event->lm_cli_idx); 6714 6715 lm_dcbx_ie_update_bacs_state(pdev, 6716 dcb_params->flags); 6717 6718 if((TRUE == is_local_ets_change)|| 6719 (TRUE == classif_change_mcp_not_aware)) 6720 { 6721 // Update HW/FW with new ETS classification configuration. 6722 lm_status = lm_dcbx_set_params_and_read_mib(pdev, 6723 is_local_ets_change, 6724 TRUE); 6725 6726 } 6727 6728 return LM_STATUS_SUCCESS; 6729 } 6730 /** 6731 * @description 6732 * Allocate indicate event bind structs. 6733 * The dcb_local_params->classif_params.classif_table is RT and 6734 * will be changed acording to the amount of entries that are 6735 * given from upper layer. 6736 * @param lm_cli_idx 6737 * 6738 * @return lm_status_t 6739 */ 6740 lm_status_t 6741 lm_dcbx_ie_initialize( 6742 INOUT struct _lm_device_t *pdev, 6743 IN const u8_t lm_cli_idx) 6744 { 6745 lm_dcbx_indicate_event_t *indicate_event = &pdev->dcbx_info.indicate_event; 6746 const u32_t classif_table_aloc_size_local = LM_DCBX_IE_CLASSIF_TABLE_ALOC_SIZE_LOCAL; 6747 const u32_t classif_table_aloc_size_remote = LM_DCBX_IE_CLASSIF_TABLE_ALOC_SIZE_REMOTE; 6748 6749 DbgBreakIf(LM_CLI_IDX_MAX != indicate_event->lm_cli_idx); 6750 DbgBreakIf ((0 == pdev->params.b_dcb_indicate_event)); 6751 6752 DbgBreakIf((NULL != indicate_event->remote_params.classif_params.classif_table) || 6753 (NULL != indicate_event->local_params.classif_params.classif_table) || 6754 (NULL != indicate_event->dcb_params_given_dbg.classif_params.classif_table)); 6755 6756 indicate_event->lm_cli_idx = lm_cli_idx; 6757 6758 // Allocate dcb_remote_params 6759 indicate_event->remote_params.classif_params.classif_table = 6760 mm_alloc_mem(pdev, classif_table_aloc_size_remote, indicate_event->lm_cli_idx); 6761 6762 if(CHK_NULL(indicate_event->remote_params.classif_params.classif_table)) 6763 { 6764 DbgBreakMsg("lm_dcbx_ie_alloc_bind_structs allocation failed remote "); 6765 return LM_STATUS_RESOURCE; 6766 } 6767 6768 // Allocate dcb_local_params 6769 //The only RT memory is the local table that can include upper layer classification entries 6770 indicate_event->local_params.classif_params.classif_table = 6771 mm_alloc_mem(pdev, classif_table_aloc_size_local, indicate_event->lm_cli_idx); 6772 6773 if(CHK_NULL(indicate_event->local_params.classif_params.classif_table)) 6774 { 6775 DbgBreakMsg("lm_dcbx_ie_alloc_bind_structs allocation failed local "); 6776 return LM_STATUS_RESOURCE; 6777 } 6778 6779 indicate_event->dcb_params_given_dbg.classif_params.classif_table = 6780 mm_alloc_mem(pdev, LM_DCBX_IE_CLASSIF_TABLE_ALOC_SIZE_DBG, indicate_event->lm_cli_idx); 6781 6782 if(CHK_NULL(indicate_event->dcb_params_given_dbg.classif_params.classif_table)) 6783 { 6784 DbgBreakMsg("lm_dcbx_ie_alloc_bind_structs allocation failed given DBG"); 6785 return LM_STATUS_RESOURCE; 6786 } 6787 6788 return LM_STATUS_SUCCESS; 6789 } 6790 /** 6791 * @description 6792 * Free indicate event structs that were allocated by RT. 6793 * This code must be done from LPME while is_indicate_event_en 6794 * is still valid to avoid a race. 6795 * @param lm_cli_idx 6796 * 6797 * @return void 6798 */ 6799 void 6800 lm_dcbx_ie_deinitialize( 6801 INOUT struct _lm_device_t *pdev, 6802 IN const u8_t lm_cli_idx) 6803 { 6804 lm_dcbx_indicate_event_t *indicate_event = &pdev->dcbx_info.indicate_event; 6805 6806 DbgBreakIf(lm_cli_idx != indicate_event->lm_cli_idx); 6807 6808 DbgBreakIf(NULL == indicate_event->local_params.classif_params.classif_table); 6809 DbgBreakIf(NULL == indicate_event->remote_params.classif_params.classif_table); 6810 DbgBreakIf(NULL == indicate_event->dcb_params_given_dbg.classif_params.classif_table); 6811 6812 lm_dcbx_ie_init_params(pdev, FALSE); 6813 } 6814