1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2001-2021 Intel Corporation 3 */ 4 5 #include "ice_common.h" 6 #include "ice_flex_pipe.h" 7 #include "ice_protocol_type.h" 8 #include "ice_flow.h" 9 10 /* For supporting double VLAN mode, it is necessary to enable or disable certain 11 * boost tcam entries. The metadata labels names that match the following 12 * prefixes will be saved to allow enabling double VLAN mode. 13 */ 14 #define ICE_DVM_PRE "BOOST_MAC_VLAN_DVM" /* enable these entries */ 15 #define ICE_SVM_PRE "BOOST_MAC_VLAN_SVM" /* disable these entries */ 16 17 /* To support tunneling entries by PF, the package will append the PF number to 18 * the label; for example TNL_VXLAN_PF0, TNL_VXLAN_PF1, TNL_VXLAN_PF2, etc. 19 */ 20 #define ICE_TNL_PRE "TNL_" 21 static const struct ice_tunnel_type_scan tnls[] = { 22 { TNL_VXLAN, "TNL_VXLAN_PF" }, 23 { TNL_GENEVE, "TNL_GENEVE_PF" }, 24 { TNL_ECPRI, "TNL_UDP_ECPRI_PF" }, 25 { TNL_LAST, "" } 26 }; 27 28 static const u32 ice_sect_lkup[ICE_BLK_COUNT][ICE_SECT_COUNT] = { 29 /* SWITCH */ 30 { 31 ICE_SID_XLT0_SW, 32 ICE_SID_XLT_KEY_BUILDER_SW, 33 ICE_SID_XLT1_SW, 34 ICE_SID_XLT2_SW, 35 ICE_SID_PROFID_TCAM_SW, 36 ICE_SID_PROFID_REDIR_SW, 37 ICE_SID_FLD_VEC_SW, 38 ICE_SID_CDID_KEY_BUILDER_SW, 39 ICE_SID_CDID_REDIR_SW 40 }, 41 42 /* ACL */ 43 { 44 ICE_SID_XLT0_ACL, 45 ICE_SID_XLT_KEY_BUILDER_ACL, 46 ICE_SID_XLT1_ACL, 47 ICE_SID_XLT2_ACL, 48 ICE_SID_PROFID_TCAM_ACL, 49 ICE_SID_PROFID_REDIR_ACL, 50 ICE_SID_FLD_VEC_ACL, 51 ICE_SID_CDID_KEY_BUILDER_ACL, 52 ICE_SID_CDID_REDIR_ACL 53 }, 54 55 /* FD */ 56 { 57 ICE_SID_XLT0_FD, 58 ICE_SID_XLT_KEY_BUILDER_FD, 59 ICE_SID_XLT1_FD, 60 ICE_SID_XLT2_FD, 61 ICE_SID_PROFID_TCAM_FD, 62 ICE_SID_PROFID_REDIR_FD, 63 ICE_SID_FLD_VEC_FD, 64 ICE_SID_CDID_KEY_BUILDER_FD, 65 ICE_SID_CDID_REDIR_FD 66 }, 67 68 /* RSS */ 69 { 70 ICE_SID_XLT0_RSS, 71 ICE_SID_XLT_KEY_BUILDER_RSS, 72 ICE_SID_XLT1_RSS, 73 ICE_SID_XLT2_RSS, 74 ICE_SID_PROFID_TCAM_RSS, 75 ICE_SID_PROFID_REDIR_RSS, 76 ICE_SID_FLD_VEC_RSS, 77 ICE_SID_CDID_KEY_BUILDER_RSS, 78 ICE_SID_CDID_REDIR_RSS 79 }, 80 81 /* PE */ 82 { 83 ICE_SID_XLT0_PE, 84 ICE_SID_XLT_KEY_BUILDER_PE, 85 ICE_SID_XLT1_PE, 86 ICE_SID_XLT2_PE, 87 ICE_SID_PROFID_TCAM_PE, 88 ICE_SID_PROFID_REDIR_PE, 89 ICE_SID_FLD_VEC_PE, 90 ICE_SID_CDID_KEY_BUILDER_PE, 91 ICE_SID_CDID_REDIR_PE 92 } 93 }; 94 95 /** 96 * ice_sect_id - returns section ID 97 * @blk: block type 98 * @sect: section type 99 * 100 * This helper function returns the proper section ID given a block type and a 101 * section type. 102 */ 103 static u32 ice_sect_id(enum ice_block blk, enum ice_sect sect) 104 { 105 return ice_sect_lkup[blk][sect]; 106 } 107 108 /** 109 * ice_pkg_val_buf 110 * @buf: pointer to the ice buffer 111 * 112 * This helper function validates a buffer's header. 113 */ 114 static struct ice_buf_hdr *ice_pkg_val_buf(struct ice_buf *buf) 115 { 116 struct ice_buf_hdr *hdr; 117 u16 section_count; 118 u16 data_end; 119 120 hdr = (struct ice_buf_hdr *)buf->buf; 121 /* verify data */ 122 section_count = LE16_TO_CPU(hdr->section_count); 123 if (section_count < ICE_MIN_S_COUNT || section_count > ICE_MAX_S_COUNT) 124 return NULL; 125 126 data_end = LE16_TO_CPU(hdr->data_end); 127 if (data_end < ICE_MIN_S_DATA_END || data_end > ICE_MAX_S_DATA_END) 128 return NULL; 129 130 return hdr; 131 } 132 133 /** 134 * ice_find_buf_table 135 * @ice_seg: pointer to the ice segment 136 * 137 * Returns the address of the buffer table within the ice segment. 138 */ 139 static struct ice_buf_table *ice_find_buf_table(struct ice_seg *ice_seg) 140 { 141 struct ice_nvm_table *nvms; 142 143 nvms = (struct ice_nvm_table *) 144 (ice_seg->device_table + 145 LE32_TO_CPU(ice_seg->device_table_count)); 146 147 return (_FORCE_ struct ice_buf_table *) 148 (nvms->vers + LE32_TO_CPU(nvms->table_count)); 149 } 150 151 /** 152 * ice_pkg_enum_buf 153 * @ice_seg: pointer to the ice segment (or NULL on subsequent calls) 154 * @state: pointer to the enum state 155 * 156 * This function will enumerate all the buffers in the ice segment. The first 157 * call is made with the ice_seg parameter non-NULL; on subsequent calls, 158 * ice_seg is set to NULL which continues the enumeration. When the function 159 * returns a NULL pointer, then the end of the buffers has been reached, or an 160 * unexpected value has been detected (for example an invalid section count or 161 * an invalid buffer end value). 162 */ 163 static struct ice_buf_hdr * 164 ice_pkg_enum_buf(struct ice_seg *ice_seg, struct ice_pkg_enum *state) 165 { 166 if (ice_seg) { 167 state->buf_table = ice_find_buf_table(ice_seg); 168 if (!state->buf_table) 169 return NULL; 170 171 state->buf_idx = 0; 172 return ice_pkg_val_buf(state->buf_table->buf_array); 173 } 174 175 if (++state->buf_idx < LE32_TO_CPU(state->buf_table->buf_count)) 176 return ice_pkg_val_buf(state->buf_table->buf_array + 177 state->buf_idx); 178 else 179 return NULL; 180 } 181 182 /** 183 * ice_pkg_advance_sect 184 * @ice_seg: pointer to the ice segment (or NULL on subsequent calls) 185 * @state: pointer to the enum state 186 * 187 * This helper function will advance the section within the ice segment, 188 * also advancing the buffer if needed. 189 */ 190 static bool 191 ice_pkg_advance_sect(struct ice_seg *ice_seg, struct ice_pkg_enum *state) 192 { 193 if (!ice_seg && !state->buf) 194 return false; 195 196 if (!ice_seg && state->buf) 197 if (++state->sect_idx < LE16_TO_CPU(state->buf->section_count)) 198 return true; 199 200 state->buf = ice_pkg_enum_buf(ice_seg, state); 201 if (!state->buf) 202 return false; 203 204 /* start of new buffer, reset section index */ 205 state->sect_idx = 0; 206 return true; 207 } 208 209 /** 210 * ice_pkg_enum_section 211 * @ice_seg: pointer to the ice segment (or NULL on subsequent calls) 212 * @state: pointer to the enum state 213 * @sect_type: section type to enumerate 214 * 215 * This function will enumerate all the sections of a particular type in the 216 * ice segment. The first call is made with the ice_seg parameter non-NULL; 217 * on subsequent calls, ice_seg is set to NULL which continues the enumeration. 218 * When the function returns a NULL pointer, then the end of the matching 219 * sections has been reached. 220 */ 221 static void * 222 ice_pkg_enum_section(struct ice_seg *ice_seg, struct ice_pkg_enum *state, 223 u32 sect_type) 224 { 225 u16 offset, size; 226 227 if (ice_seg) 228 state->type = sect_type; 229 230 if (!ice_pkg_advance_sect(ice_seg, state)) 231 return NULL; 232 233 /* scan for next matching section */ 234 while (state->buf->section_entry[state->sect_idx].type != 235 CPU_TO_LE32(state->type)) 236 if (!ice_pkg_advance_sect(NULL, state)) 237 return NULL; 238 239 /* validate section */ 240 offset = LE16_TO_CPU(state->buf->section_entry[state->sect_idx].offset); 241 if (offset < ICE_MIN_S_OFF || offset > ICE_MAX_S_OFF) 242 return NULL; 243 244 size = LE16_TO_CPU(state->buf->section_entry[state->sect_idx].size); 245 if (size < ICE_MIN_S_SZ || size > ICE_MAX_S_SZ) 246 return NULL; 247 248 /* make sure the section fits in the buffer */ 249 if (offset + size > ICE_PKG_BUF_SIZE) 250 return NULL; 251 252 state->sect_type = 253 LE32_TO_CPU(state->buf->section_entry[state->sect_idx].type); 254 255 /* calc pointer to this section */ 256 state->sect = ((u8 *)state->buf) + 257 LE16_TO_CPU(state->buf->section_entry[state->sect_idx].offset); 258 259 return state->sect; 260 } 261 262 /** 263 * ice_pkg_enum_entry 264 * @ice_seg: pointer to the ice segment (or NULL on subsequent calls) 265 * @state: pointer to the enum state 266 * @sect_type: section type to enumerate 267 * @offset: pointer to variable that receives the offset in the table (optional) 268 * @handler: function that handles access to the entries into the section type 269 * 270 * This function will enumerate all the entries in particular section type in 271 * the ice segment. The first call is made with the ice_seg parameter non-NULL; 272 * on subsequent calls, ice_seg is set to NULL which continues the enumeration. 273 * When the function returns a NULL pointer, then the end of the entries has 274 * been reached. 275 * 276 * Since each section may have a different header and entry size, the handler 277 * function is needed to determine the number and location entries in each 278 * section. 279 * 280 * The offset parameter is optional, but should be used for sections that 281 * contain an offset for each section table. For such cases, the section handler 282 * function must return the appropriate offset + index to give the absolution 283 * offset for each entry. For example, if the base for a section's header 284 * indicates a base offset of 10, and the index for the entry is 2, then 285 * section handler function should set the offset to 10 + 2 = 12. 286 */ 287 static void * 288 ice_pkg_enum_entry(struct ice_seg *ice_seg, struct ice_pkg_enum *state, 289 u32 sect_type, u32 *offset, 290 void *(*handler)(u32 sect_type, void *section, 291 u32 index, u32 *offset)) 292 { 293 void *entry; 294 295 if (ice_seg) { 296 if (!handler) 297 return NULL; 298 299 if (!ice_pkg_enum_section(ice_seg, state, sect_type)) 300 return NULL; 301 302 state->entry_idx = 0; 303 state->handler = handler; 304 } else { 305 state->entry_idx++; 306 } 307 308 if (!state->handler) 309 return NULL; 310 311 /* get entry */ 312 entry = state->handler(state->sect_type, state->sect, state->entry_idx, 313 offset); 314 if (!entry) { 315 /* end of a section, look for another section of this type */ 316 if (!ice_pkg_enum_section(NULL, state, 0)) 317 return NULL; 318 319 state->entry_idx = 0; 320 entry = state->handler(state->sect_type, state->sect, 321 state->entry_idx, offset); 322 } 323 324 return entry; 325 } 326 327 /** 328 * ice_hw_ptype_ena - check if the PTYPE is enabled or not 329 * @hw: pointer to the HW structure 330 * @ptype: the hardware PTYPE 331 */ 332 bool ice_hw_ptype_ena(struct ice_hw *hw, u16 ptype) 333 { 334 return ptype < ICE_FLOW_PTYPE_MAX && 335 ice_is_bit_set(hw->hw_ptype, ptype); 336 } 337 338 /** 339 * ice_marker_ptype_tcam_handler 340 * @sect_type: section type 341 * @section: pointer to section 342 * @index: index of the Marker PType TCAM entry to be returned 343 * @offset: pointer to receive absolute offset, always 0 for ptype TCAM sections 344 * 345 * This is a callback function that can be passed to ice_pkg_enum_entry. 346 * Handles enumeration of individual Marker PType TCAM entries. 347 */ 348 static void * 349 ice_marker_ptype_tcam_handler(u32 sect_type, void *section, u32 index, 350 u32 *offset) 351 { 352 struct ice_marker_ptype_tcam_section *marker_ptype; 353 354 if (!section) 355 return NULL; 356 357 if (sect_type != ICE_SID_RXPARSER_MARKER_PTYPE) 358 return NULL; 359 360 if (index > ICE_MAX_MARKER_PTYPE_TCAMS_IN_BUF) 361 return NULL; 362 363 if (offset) 364 *offset = 0; 365 366 marker_ptype = (struct ice_marker_ptype_tcam_section *)section; 367 if (index >= LE16_TO_CPU(marker_ptype->count)) 368 return NULL; 369 370 return marker_ptype->tcam + index; 371 } 372 373 /** 374 * ice_fill_hw_ptype - fill the enabled PTYPE bit information 375 * @hw: pointer to the HW structure 376 */ 377 static void 378 ice_fill_hw_ptype(struct ice_hw *hw) 379 { 380 struct ice_marker_ptype_tcam_entry *tcam; 381 struct ice_seg *seg = hw->seg; 382 struct ice_pkg_enum state; 383 384 ice_zero_bitmap(hw->hw_ptype, ICE_FLOW_PTYPE_MAX); 385 if (!seg) 386 return; 387 388 ice_memset(&state, 0, sizeof(state), ICE_NONDMA_MEM); 389 390 do { 391 tcam = (struct ice_marker_ptype_tcam_entry *) 392 ice_pkg_enum_entry(seg, &state, 393 ICE_SID_RXPARSER_MARKER_PTYPE, NULL, 394 ice_marker_ptype_tcam_handler); 395 if (tcam && 396 LE16_TO_CPU(tcam->addr) < ICE_MARKER_PTYPE_TCAM_ADDR_MAX && 397 LE16_TO_CPU(tcam->ptype) < ICE_FLOW_PTYPE_MAX) 398 ice_set_bit(LE16_TO_CPU(tcam->ptype), hw->hw_ptype); 399 400 seg = NULL; 401 } while (tcam); 402 } 403 404 /** 405 * ice_boost_tcam_handler 406 * @sect_type: section type 407 * @section: pointer to section 408 * @index: index of the boost TCAM entry to be returned 409 * @offset: pointer to receive absolute offset, always 0 for boost TCAM sections 410 * 411 * This is a callback function that can be passed to ice_pkg_enum_entry. 412 * Handles enumeration of individual boost TCAM entries. 413 */ 414 static void * 415 ice_boost_tcam_handler(u32 sect_type, void *section, u32 index, u32 *offset) 416 { 417 struct ice_boost_tcam_section *boost; 418 419 if (!section) 420 return NULL; 421 422 if (sect_type != ICE_SID_RXPARSER_BOOST_TCAM) 423 return NULL; 424 425 if (index > ICE_MAX_BST_TCAMS_IN_BUF) 426 return NULL; 427 428 if (offset) 429 *offset = 0; 430 431 boost = (struct ice_boost_tcam_section *)section; 432 if (index >= LE16_TO_CPU(boost->count)) 433 return NULL; 434 435 return boost->tcam + index; 436 } 437 438 /** 439 * ice_find_boost_entry 440 * @ice_seg: pointer to the ice segment (non-NULL) 441 * @addr: Boost TCAM address of entry to search for 442 * @entry: returns pointer to the entry 443 * 444 * Finds a particular Boost TCAM entry and returns a pointer to that entry 445 * if it is found. The ice_seg parameter must not be NULL since the first call 446 * to ice_pkg_enum_entry requires a pointer to an actual ice_segment structure. 447 */ 448 static enum ice_status 449 ice_find_boost_entry(struct ice_seg *ice_seg, u16 addr, 450 struct ice_boost_tcam_entry **entry) 451 { 452 struct ice_boost_tcam_entry *tcam; 453 struct ice_pkg_enum state; 454 455 ice_memset(&state, 0, sizeof(state), ICE_NONDMA_MEM); 456 457 if (!ice_seg) 458 return ICE_ERR_PARAM; 459 460 do { 461 tcam = (struct ice_boost_tcam_entry *) 462 ice_pkg_enum_entry(ice_seg, &state, 463 ICE_SID_RXPARSER_BOOST_TCAM, NULL, 464 ice_boost_tcam_handler); 465 if (tcam && LE16_TO_CPU(tcam->addr) == addr) { 466 *entry = tcam; 467 return ICE_SUCCESS; 468 } 469 470 ice_seg = NULL; 471 } while (tcam); 472 473 *entry = NULL; 474 return ICE_ERR_CFG; 475 } 476 477 /** 478 * ice_label_enum_handler 479 * @sect_type: section type 480 * @section: pointer to section 481 * @index: index of the label entry to be returned 482 * @offset: pointer to receive absolute offset, always zero for label sections 483 * 484 * This is a callback function that can be passed to ice_pkg_enum_entry. 485 * Handles enumeration of individual label entries. 486 */ 487 static void * 488 ice_label_enum_handler(u32 __ALWAYS_UNUSED sect_type, void *section, u32 index, 489 u32 *offset) 490 { 491 struct ice_label_section *labels; 492 493 if (!section) 494 return NULL; 495 496 if (index > ICE_MAX_LABELS_IN_BUF) 497 return NULL; 498 499 if (offset) 500 *offset = 0; 501 502 labels = (struct ice_label_section *)section; 503 if (index >= LE16_TO_CPU(labels->count)) 504 return NULL; 505 506 return labels->label + index; 507 } 508 509 /** 510 * ice_enum_labels 511 * @ice_seg: pointer to the ice segment (NULL on subsequent calls) 512 * @type: the section type that will contain the label (0 on subsequent calls) 513 * @state: ice_pkg_enum structure that will hold the state of the enumeration 514 * @value: pointer to a value that will return the label's value if found 515 * 516 * Enumerates a list of labels in the package. The caller will call 517 * ice_enum_labels(ice_seg, type, ...) to start the enumeration, then call 518 * ice_enum_labels(NULL, 0, ...) to continue. When the function returns a NULL 519 * the end of the list has been reached. 520 */ 521 static char * 522 ice_enum_labels(struct ice_seg *ice_seg, u32 type, struct ice_pkg_enum *state, 523 u16 *value) 524 { 525 struct ice_label *label; 526 527 /* Check for valid label section on first call */ 528 if (type && !(type >= ICE_SID_LBL_FIRST && type <= ICE_SID_LBL_LAST)) 529 return NULL; 530 531 label = (struct ice_label *)ice_pkg_enum_entry(ice_seg, state, type, 532 NULL, 533 ice_label_enum_handler); 534 if (!label) 535 return NULL; 536 537 *value = LE16_TO_CPU(label->value); 538 return label->name; 539 } 540 541 /** 542 * ice_add_tunnel_hint 543 * @hw: pointer to the HW structure 544 * @label_name: label text 545 * @val: value of the tunnel port boost entry 546 */ 547 static void ice_add_tunnel_hint(struct ice_hw *hw, char *label_name, u16 val) 548 { 549 if (hw->tnl.count < ICE_TUNNEL_MAX_ENTRIES) { 550 u16 i; 551 552 for (i = 0; tnls[i].type != TNL_LAST; i++) { 553 size_t len = strlen(tnls[i].label_prefix); 554 555 /* Look for matching label start, before continuing */ 556 if (strncmp(label_name, tnls[i].label_prefix, len)) 557 continue; 558 559 /* Make sure this label matches our PF. Note that the PF 560 * character ('0' - '7') will be located where our 561 * prefix string's null terminator is located. 562 */ 563 if ((label_name[len] - '0') == hw->pf_id) { 564 hw->tnl.tbl[hw->tnl.count].type = tnls[i].type; 565 hw->tnl.tbl[hw->tnl.count].valid = false; 566 hw->tnl.tbl[hw->tnl.count].in_use = false; 567 hw->tnl.tbl[hw->tnl.count].marked = false; 568 hw->tnl.tbl[hw->tnl.count].boost_addr = val; 569 hw->tnl.tbl[hw->tnl.count].port = 0; 570 hw->tnl.count++; 571 break; 572 } 573 } 574 } 575 } 576 577 /** 578 * ice_add_dvm_hint 579 * @hw: pointer to the HW structure 580 * @val: value of the boost entry 581 * @enable: true if entry needs to be enabled, or false if needs to be disabled 582 */ 583 static void ice_add_dvm_hint(struct ice_hw *hw, u16 val, bool enable) 584 { 585 if (hw->dvm_upd.count < ICE_DVM_MAX_ENTRIES) { 586 hw->dvm_upd.tbl[hw->dvm_upd.count].boost_addr = val; 587 hw->dvm_upd.tbl[hw->dvm_upd.count].enable = enable; 588 hw->dvm_upd.count++; 589 } 590 } 591 592 /** 593 * ice_init_pkg_hints 594 * @hw: pointer to the HW structure 595 * @ice_seg: pointer to the segment of the package scan (non-NULL) 596 * 597 * This function will scan the package and save off relevant information 598 * (hints or metadata) for driver use. The ice_seg parameter must not be NULL 599 * since the first call to ice_enum_labels requires a pointer to an actual 600 * ice_seg structure. 601 */ 602 static void ice_init_pkg_hints(struct ice_hw *hw, struct ice_seg *ice_seg) 603 { 604 struct ice_pkg_enum state; 605 char *label_name; 606 u16 val; 607 int i; 608 609 ice_memset(&hw->tnl, 0, sizeof(hw->tnl), ICE_NONDMA_MEM); 610 ice_memset(&state, 0, sizeof(state), ICE_NONDMA_MEM); 611 612 if (!ice_seg) 613 return; 614 615 label_name = ice_enum_labels(ice_seg, ICE_SID_LBL_RXPARSER_TMEM, &state, 616 &val); 617 618 while (label_name) { 619 if (!strncmp(label_name, ICE_TNL_PRE, strlen(ICE_TNL_PRE))) 620 /* check for a tunnel entry */ 621 ice_add_tunnel_hint(hw, label_name, val); 622 623 /* check for a dvm mode entry */ 624 else if (!strncmp(label_name, ICE_DVM_PRE, strlen(ICE_DVM_PRE))) 625 ice_add_dvm_hint(hw, val, true); 626 627 /* check for a svm mode entry */ 628 else if (!strncmp(label_name, ICE_SVM_PRE, strlen(ICE_SVM_PRE))) 629 ice_add_dvm_hint(hw, val, false); 630 631 label_name = ice_enum_labels(NULL, 0, &state, &val); 632 } 633 634 /* Cache the appropriate boost TCAM entry pointers for tunnels */ 635 for (i = 0; i < hw->tnl.count; i++) { 636 ice_find_boost_entry(ice_seg, hw->tnl.tbl[i].boost_addr, 637 &hw->tnl.tbl[i].boost_entry); 638 if (hw->tnl.tbl[i].boost_entry) 639 hw->tnl.tbl[i].valid = true; 640 } 641 642 /* Cache the appropriate boost TCAM entry pointers for DVM and SVM */ 643 for (i = 0; i < hw->dvm_upd.count; i++) 644 ice_find_boost_entry(ice_seg, hw->dvm_upd.tbl[i].boost_addr, 645 &hw->dvm_upd.tbl[i].boost_entry); 646 } 647 648 /* Key creation */ 649 650 #define ICE_DC_KEY 0x1 /* don't care */ 651 #define ICE_DC_KEYINV 0x1 652 #define ICE_NM_KEY 0x0 /* never match */ 653 #define ICE_NM_KEYINV 0x0 654 #define ICE_0_KEY 0x1 /* match 0 */ 655 #define ICE_0_KEYINV 0x0 656 #define ICE_1_KEY 0x0 /* match 1 */ 657 #define ICE_1_KEYINV 0x1 658 659 /** 660 * ice_gen_key_word - generate 16-bits of a key/mask word 661 * @val: the value 662 * @valid: valid bits mask (change only the valid bits) 663 * @dont_care: don't care mask 664 * @nvr_mtch: never match mask 665 * @key: pointer to an array of where the resulting key portion 666 * @key_inv: pointer to an array of where the resulting key invert portion 667 * 668 * This function generates 16-bits from a 8-bit value, an 8-bit don't care mask 669 * and an 8-bit never match mask. The 16-bits of output are divided into 8 bits 670 * of key and 8 bits of key invert. 671 * 672 * '0' = b01, always match a 0 bit 673 * '1' = b10, always match a 1 bit 674 * '?' = b11, don't care bit (always matches) 675 * '~' = b00, never match bit 676 * 677 * Input: 678 * val: b0 1 0 1 0 1 679 * dont_care: b0 0 1 1 0 0 680 * never_mtch: b0 0 0 0 1 1 681 * ------------------------------ 682 * Result: key: b01 10 11 11 00 00 683 */ 684 static enum ice_status 685 ice_gen_key_word(u8 val, u8 valid, u8 dont_care, u8 nvr_mtch, u8 *key, 686 u8 *key_inv) 687 { 688 u8 in_key = *key, in_key_inv = *key_inv; 689 u8 i; 690 691 /* 'dont_care' and 'nvr_mtch' masks cannot overlap */ 692 if ((dont_care ^ nvr_mtch) != (dont_care | nvr_mtch)) 693 return ICE_ERR_CFG; 694 695 *key = 0; 696 *key_inv = 0; 697 698 /* encode the 8 bits into 8-bit key and 8-bit key invert */ 699 for (i = 0; i < 8; i++) { 700 *key >>= 1; 701 *key_inv >>= 1; 702 703 if (!(valid & 0x1)) { /* change only valid bits */ 704 *key |= (in_key & 0x1) << 7; 705 *key_inv |= (in_key_inv & 0x1) << 7; 706 } else if (dont_care & 0x1) { /* don't care bit */ 707 *key |= ICE_DC_KEY << 7; 708 *key_inv |= ICE_DC_KEYINV << 7; 709 } else if (nvr_mtch & 0x1) { /* never match bit */ 710 *key |= ICE_NM_KEY << 7; 711 *key_inv |= ICE_NM_KEYINV << 7; 712 } else if (val & 0x01) { /* exact 1 match */ 713 *key |= ICE_1_KEY << 7; 714 *key_inv |= ICE_1_KEYINV << 7; 715 } else { /* exact 0 match */ 716 *key |= ICE_0_KEY << 7; 717 *key_inv |= ICE_0_KEYINV << 7; 718 } 719 720 dont_care >>= 1; 721 nvr_mtch >>= 1; 722 valid >>= 1; 723 val >>= 1; 724 in_key >>= 1; 725 in_key_inv >>= 1; 726 } 727 728 return ICE_SUCCESS; 729 } 730 731 /** 732 * ice_bits_max_set - determine if the number of bits set is within a maximum 733 * @mask: pointer to the byte array which is the mask 734 * @size: the number of bytes in the mask 735 * @max: the max number of set bits 736 * 737 * This function determines if there are at most 'max' number of bits set in an 738 * array. Returns true if the number for bits set is <= max or will return false 739 * otherwise. 740 */ 741 static bool ice_bits_max_set(const u8 *mask, u16 size, u16 max) 742 { 743 u16 count = 0; 744 u16 i; 745 746 /* check each byte */ 747 for (i = 0; i < size; i++) { 748 /* if 0, go to next byte */ 749 if (!mask[i]) 750 continue; 751 752 /* We know there is at least one set bit in this byte because of 753 * the above check; if we already have found 'max' number of 754 * bits set, then we can return failure now. 755 */ 756 if (count == max) 757 return false; 758 759 /* count the bits in this byte, checking threshold */ 760 count += ice_hweight8(mask[i]); 761 if (count > max) 762 return false; 763 } 764 765 return true; 766 } 767 768 /** 769 * ice_set_key - generate a variable sized key with multiples of 16-bits 770 * @key: pointer to where the key will be stored 771 * @size: the size of the complete key in bytes (must be even) 772 * @val: array of 8-bit values that makes up the value portion of the key 773 * @upd: array of 8-bit masks that determine what key portion to update 774 * @dc: array of 8-bit masks that make up the don't care mask 775 * @nm: array of 8-bit masks that make up the never match mask 776 * @off: the offset of the first byte in the key to update 777 * @len: the number of bytes in the key update 778 * 779 * This function generates a key from a value, a don't care mask and a never 780 * match mask. 781 * upd, dc, and nm are optional parameters, and can be NULL: 782 * upd == NULL --> upd mask is all 1's (update all bits) 783 * dc == NULL --> dc mask is all 0's (no don't care bits) 784 * nm == NULL --> nm mask is all 0's (no never match bits) 785 */ 786 enum ice_status 787 ice_set_key(u8 *key, u16 size, u8 *val, u8 *upd, u8 *dc, u8 *nm, u16 off, 788 u16 len) 789 { 790 u16 half_size; 791 u16 i; 792 793 /* size must be a multiple of 2 bytes. */ 794 if (size % 2) 795 return ICE_ERR_CFG; 796 half_size = size / 2; 797 798 if (off + len > half_size) 799 return ICE_ERR_CFG; 800 801 /* Make sure at most one bit is set in the never match mask. Having more 802 * than one never match mask bit set will cause HW to consume excessive 803 * power otherwise; this is a power management efficiency check. 804 */ 805 #define ICE_NVR_MTCH_BITS_MAX 1 806 if (nm && !ice_bits_max_set(nm, len, ICE_NVR_MTCH_BITS_MAX)) 807 return ICE_ERR_CFG; 808 809 for (i = 0; i < len; i++) 810 if (ice_gen_key_word(val[i], upd ? upd[i] : 0xff, 811 dc ? dc[i] : 0, nm ? nm[i] : 0, 812 key + off + i, key + half_size + off + i)) 813 return ICE_ERR_CFG; 814 815 return ICE_SUCCESS; 816 } 817 818 /** 819 * ice_acquire_global_cfg_lock 820 * @hw: pointer to the HW structure 821 * @access: access type (read or write) 822 * 823 * This function will request ownership of the global config lock for reading 824 * or writing of the package. When attempting to obtain write access, the 825 * caller must check for the following two return values: 826 * 827 * ICE_SUCCESS - Means the caller has acquired the global config lock 828 * and can perform writing of the package. 829 * ICE_ERR_AQ_NO_WORK - Indicates another driver has already written the 830 * package or has found that no update was necessary; in 831 * this case, the caller can just skip performing any 832 * update of the package. 833 */ 834 static enum ice_status 835 ice_acquire_global_cfg_lock(struct ice_hw *hw, 836 enum ice_aq_res_access_type access) 837 { 838 enum ice_status status; 839 840 ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__); 841 842 status = ice_acquire_res(hw, ICE_GLOBAL_CFG_LOCK_RES_ID, access, 843 ICE_GLOBAL_CFG_LOCK_TIMEOUT); 844 845 if (status == ICE_ERR_AQ_NO_WORK) 846 ice_debug(hw, ICE_DBG_PKG, "Global config lock: No work to do\n"); 847 848 return status; 849 } 850 851 /** 852 * ice_release_global_cfg_lock 853 * @hw: pointer to the HW structure 854 * 855 * This function will release the global config lock. 856 */ 857 static void ice_release_global_cfg_lock(struct ice_hw *hw) 858 { 859 ice_release_res(hw, ICE_GLOBAL_CFG_LOCK_RES_ID); 860 } 861 862 /** 863 * ice_acquire_change_lock 864 * @hw: pointer to the HW structure 865 * @access: access type (read or write) 866 * 867 * This function will request ownership of the change lock. 868 */ 869 enum ice_status 870 ice_acquire_change_lock(struct ice_hw *hw, enum ice_aq_res_access_type access) 871 { 872 ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__); 873 874 return ice_acquire_res(hw, ICE_CHANGE_LOCK_RES_ID, access, 875 ICE_CHANGE_LOCK_TIMEOUT); 876 } 877 878 /** 879 * ice_release_change_lock 880 * @hw: pointer to the HW structure 881 * 882 * This function will release the change lock using the proper Admin Command. 883 */ 884 void ice_release_change_lock(struct ice_hw *hw) 885 { 886 ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__); 887 888 ice_release_res(hw, ICE_CHANGE_LOCK_RES_ID); 889 } 890 891 /** 892 * ice_aq_download_pkg 893 * @hw: pointer to the hardware structure 894 * @pkg_buf: the package buffer to transfer 895 * @buf_size: the size of the package buffer 896 * @last_buf: last buffer indicator 897 * @error_offset: returns error offset 898 * @error_info: returns error information 899 * @cd: pointer to command details structure or NULL 900 * 901 * Download Package (0x0C40) 902 */ 903 static enum ice_status 904 ice_aq_download_pkg(struct ice_hw *hw, struct ice_buf_hdr *pkg_buf, 905 u16 buf_size, bool last_buf, u32 *error_offset, 906 u32 *error_info, struct ice_sq_cd *cd) 907 { 908 struct ice_aqc_download_pkg *cmd; 909 struct ice_aq_desc desc; 910 enum ice_status status; 911 912 ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__); 913 914 if (error_offset) 915 *error_offset = 0; 916 if (error_info) 917 *error_info = 0; 918 919 cmd = &desc.params.download_pkg; 920 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_download_pkg); 921 desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD); 922 923 if (last_buf) 924 cmd->flags |= ICE_AQC_DOWNLOAD_PKG_LAST_BUF; 925 926 status = ice_aq_send_cmd(hw, &desc, pkg_buf, buf_size, cd); 927 if (status == ICE_ERR_AQ_ERROR) { 928 /* Read error from buffer only when the FW returned an error */ 929 struct ice_aqc_download_pkg_resp *resp; 930 931 resp = (struct ice_aqc_download_pkg_resp *)pkg_buf; 932 if (error_offset) 933 *error_offset = LE32_TO_CPU(resp->error_offset); 934 if (error_info) 935 *error_info = LE32_TO_CPU(resp->error_info); 936 } 937 938 return status; 939 } 940 941 /** 942 * ice_aq_upload_section 943 * @hw: pointer to the hardware structure 944 * @pkg_buf: the package buffer which will receive the section 945 * @buf_size: the size of the package buffer 946 * @cd: pointer to command details structure or NULL 947 * 948 * Upload Section (0x0C41) 949 */ 950 enum ice_status 951 ice_aq_upload_section(struct ice_hw *hw, struct ice_buf_hdr *pkg_buf, 952 u16 buf_size, struct ice_sq_cd *cd) 953 { 954 struct ice_aq_desc desc; 955 956 ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__); 957 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_upload_section); 958 desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD); 959 960 return ice_aq_send_cmd(hw, &desc, pkg_buf, buf_size, cd); 961 } 962 963 /** 964 * ice_aq_update_pkg 965 * @hw: pointer to the hardware structure 966 * @pkg_buf: the package cmd buffer 967 * @buf_size: the size of the package cmd buffer 968 * @last_buf: last buffer indicator 969 * @error_offset: returns error offset 970 * @error_info: returns error information 971 * @cd: pointer to command details structure or NULL 972 * 973 * Update Package (0x0C42) 974 */ 975 static enum ice_status 976 ice_aq_update_pkg(struct ice_hw *hw, struct ice_buf_hdr *pkg_buf, u16 buf_size, 977 bool last_buf, u32 *error_offset, u32 *error_info, 978 struct ice_sq_cd *cd) 979 { 980 struct ice_aqc_download_pkg *cmd; 981 struct ice_aq_desc desc; 982 enum ice_status status; 983 984 ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__); 985 986 if (error_offset) 987 *error_offset = 0; 988 if (error_info) 989 *error_info = 0; 990 991 cmd = &desc.params.download_pkg; 992 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_update_pkg); 993 desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD); 994 995 if (last_buf) 996 cmd->flags |= ICE_AQC_DOWNLOAD_PKG_LAST_BUF; 997 998 status = ice_aq_send_cmd(hw, &desc, pkg_buf, buf_size, cd); 999 if (status == ICE_ERR_AQ_ERROR) { 1000 /* Read error from buffer only when the FW returned an error */ 1001 struct ice_aqc_download_pkg_resp *resp; 1002 1003 resp = (struct ice_aqc_download_pkg_resp *)pkg_buf; 1004 if (error_offset) 1005 *error_offset = LE32_TO_CPU(resp->error_offset); 1006 if (error_info) 1007 *error_info = LE32_TO_CPU(resp->error_info); 1008 } 1009 1010 return status; 1011 } 1012 1013 /** 1014 * ice_find_seg_in_pkg 1015 * @hw: pointer to the hardware structure 1016 * @seg_type: the segment type to search for (i.e., SEGMENT_TYPE_CPK) 1017 * @pkg_hdr: pointer to the package header to be searched 1018 * 1019 * This function searches a package file for a particular segment type. On 1020 * success it returns a pointer to the segment header, otherwise it will 1021 * return NULL. 1022 */ 1023 static struct ice_generic_seg_hdr * 1024 ice_find_seg_in_pkg(struct ice_hw *hw, u32 seg_type, 1025 struct ice_pkg_hdr *pkg_hdr) 1026 { 1027 u32 i; 1028 1029 ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__); 1030 ice_debug(hw, ICE_DBG_PKG, "Package format version: %d.%d.%d.%d\n", 1031 pkg_hdr->pkg_format_ver.major, pkg_hdr->pkg_format_ver.minor, 1032 pkg_hdr->pkg_format_ver.update, 1033 pkg_hdr->pkg_format_ver.draft); 1034 1035 /* Search all package segments for the requested segment type */ 1036 for (i = 0; i < LE32_TO_CPU(pkg_hdr->seg_count); i++) { 1037 struct ice_generic_seg_hdr *seg; 1038 1039 seg = (struct ice_generic_seg_hdr *) 1040 ((u8 *)pkg_hdr + LE32_TO_CPU(pkg_hdr->seg_offset[i])); 1041 1042 if (LE32_TO_CPU(seg->seg_type) == seg_type) 1043 return seg; 1044 } 1045 1046 return NULL; 1047 } 1048 1049 /** 1050 * ice_update_pkg_no_lock 1051 * @hw: pointer to the hardware structure 1052 * @bufs: pointer to an array of buffers 1053 * @count: the number of buffers in the array 1054 */ 1055 static enum ice_status 1056 ice_update_pkg_no_lock(struct ice_hw *hw, struct ice_buf *bufs, u32 count) 1057 { 1058 enum ice_status status = ICE_SUCCESS; 1059 u32 i; 1060 1061 for (i = 0; i < count; i++) { 1062 struct ice_buf_hdr *bh = (struct ice_buf_hdr *)(bufs + i); 1063 bool last = ((i + 1) == count); 1064 u32 offset, info; 1065 1066 status = ice_aq_update_pkg(hw, bh, LE16_TO_CPU(bh->data_end), 1067 last, &offset, &info, NULL); 1068 1069 if (status) { 1070 ice_debug(hw, ICE_DBG_PKG, "Update pkg failed: err %d off %d inf %d\n", 1071 status, offset, info); 1072 break; 1073 } 1074 } 1075 1076 return status; 1077 } 1078 1079 /** 1080 * ice_update_pkg 1081 * @hw: pointer to the hardware structure 1082 * @bufs: pointer to an array of buffers 1083 * @count: the number of buffers in the array 1084 * 1085 * Obtains change lock and updates package. 1086 */ 1087 enum ice_status 1088 ice_update_pkg(struct ice_hw *hw, struct ice_buf *bufs, u32 count) 1089 { 1090 enum ice_status status; 1091 1092 status = ice_acquire_change_lock(hw, ICE_RES_WRITE); 1093 if (status) 1094 return status; 1095 1096 status = ice_update_pkg_no_lock(hw, bufs, count); 1097 1098 ice_release_change_lock(hw); 1099 1100 return status; 1101 } 1102 1103 /** 1104 * ice_dwnld_cfg_bufs 1105 * @hw: pointer to the hardware structure 1106 * @bufs: pointer to an array of buffers 1107 * @count: the number of buffers in the array 1108 * 1109 * Obtains global config lock and downloads the package configuration buffers 1110 * to the firmware. Metadata buffers are skipped, and the first metadata buffer 1111 * found indicates that the rest of the buffers are all metadata buffers. 1112 */ 1113 static enum ice_status 1114 ice_dwnld_cfg_bufs(struct ice_hw *hw, struct ice_buf *bufs, u32 count) 1115 { 1116 enum ice_status status; 1117 struct ice_buf_hdr *bh; 1118 u32 offset, info, i; 1119 1120 if (!bufs || !count) 1121 return ICE_ERR_PARAM; 1122 1123 /* If the first buffer's first section has its metadata bit set 1124 * then there are no buffers to be downloaded, and the operation is 1125 * considered a success. 1126 */ 1127 bh = (struct ice_buf_hdr *)bufs; 1128 if (LE32_TO_CPU(bh->section_entry[0].type) & ICE_METADATA_BUF) 1129 return ICE_SUCCESS; 1130 1131 /* reset pkg_dwnld_status in case this function is called in the 1132 * reset/rebuild flow 1133 */ 1134 hw->pkg_dwnld_status = ICE_AQ_RC_OK; 1135 1136 status = ice_acquire_global_cfg_lock(hw, ICE_RES_WRITE); 1137 if (status) { 1138 if (status == ICE_ERR_AQ_NO_WORK) 1139 hw->pkg_dwnld_status = ICE_AQ_RC_EEXIST; 1140 else 1141 hw->pkg_dwnld_status = hw->adminq.sq_last_status; 1142 return status; 1143 } 1144 1145 for (i = 0; i < count; i++) { 1146 bool last = ((i + 1) == count); 1147 1148 if (!last) { 1149 /* check next buffer for metadata flag */ 1150 bh = (struct ice_buf_hdr *)(bufs + i + 1); 1151 1152 /* A set metadata flag in the next buffer will signal 1153 * that the current buffer will be the last buffer 1154 * downloaded 1155 */ 1156 if (LE16_TO_CPU(bh->section_count)) 1157 if (LE32_TO_CPU(bh->section_entry[0].type) & 1158 ICE_METADATA_BUF) 1159 last = true; 1160 } 1161 1162 bh = (struct ice_buf_hdr *)(bufs + i); 1163 1164 status = ice_aq_download_pkg(hw, bh, ICE_PKG_BUF_SIZE, last, 1165 &offset, &info, NULL); 1166 1167 /* Save AQ status from download package */ 1168 hw->pkg_dwnld_status = hw->adminq.sq_last_status; 1169 if (status) { 1170 ice_debug(hw, ICE_DBG_PKG, "Pkg download failed: err %d off %d inf %d\n", 1171 status, offset, info); 1172 break; 1173 } 1174 1175 if (last) 1176 break; 1177 } 1178 1179 if (!status) { 1180 status = ice_set_vlan_mode(hw); 1181 if (status) 1182 ice_debug(hw, ICE_DBG_PKG, "Failed to set VLAN mode: err %d\n", 1183 status); 1184 } 1185 1186 ice_release_global_cfg_lock(hw); 1187 1188 return status; 1189 } 1190 1191 /** 1192 * ice_aq_get_pkg_info_list 1193 * @hw: pointer to the hardware structure 1194 * @pkg_info: the buffer which will receive the information list 1195 * @buf_size: the size of the pkg_info information buffer 1196 * @cd: pointer to command details structure or NULL 1197 * 1198 * Get Package Info List (0x0C43) 1199 */ 1200 static enum ice_status 1201 ice_aq_get_pkg_info_list(struct ice_hw *hw, 1202 struct ice_aqc_get_pkg_info_resp *pkg_info, 1203 u16 buf_size, struct ice_sq_cd *cd) 1204 { 1205 struct ice_aq_desc desc; 1206 1207 ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__); 1208 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_pkg_info_list); 1209 1210 return ice_aq_send_cmd(hw, &desc, pkg_info, buf_size, cd); 1211 } 1212 1213 /** 1214 * ice_download_pkg 1215 * @hw: pointer to the hardware structure 1216 * @ice_seg: pointer to the segment of the package to be downloaded 1217 * 1218 * Handles the download of a complete package. 1219 */ 1220 static enum ice_status 1221 ice_download_pkg(struct ice_hw *hw, struct ice_seg *ice_seg) 1222 { 1223 struct ice_buf_table *ice_buf_tbl; 1224 enum ice_status status; 1225 1226 ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__); 1227 ice_debug(hw, ICE_DBG_PKG, "Segment format version: %d.%d.%d.%d\n", 1228 ice_seg->hdr.seg_format_ver.major, 1229 ice_seg->hdr.seg_format_ver.minor, 1230 ice_seg->hdr.seg_format_ver.update, 1231 ice_seg->hdr.seg_format_ver.draft); 1232 1233 ice_debug(hw, ICE_DBG_PKG, "Seg: type 0x%X, size %d, name %s\n", 1234 LE32_TO_CPU(ice_seg->hdr.seg_type), 1235 LE32_TO_CPU(ice_seg->hdr.seg_size), ice_seg->hdr.seg_id); 1236 1237 ice_buf_tbl = ice_find_buf_table(ice_seg); 1238 1239 ice_debug(hw, ICE_DBG_PKG, "Seg buf count: %d\n", 1240 LE32_TO_CPU(ice_buf_tbl->buf_count)); 1241 1242 status = ice_dwnld_cfg_bufs(hw, ice_buf_tbl->buf_array, 1243 LE32_TO_CPU(ice_buf_tbl->buf_count)); 1244 1245 ice_cache_vlan_mode(hw); 1246 1247 if (ice_is_dvm_ena(hw)) 1248 ice_change_proto_id_to_dvm(); 1249 1250 return status; 1251 } 1252 1253 /** 1254 * ice_init_pkg_info 1255 * @hw: pointer to the hardware structure 1256 * @pkg_hdr: pointer to the driver's package hdr 1257 * 1258 * Saves off the package details into the HW structure. 1259 */ 1260 static enum ice_status 1261 ice_init_pkg_info(struct ice_hw *hw, struct ice_pkg_hdr *pkg_hdr) 1262 { 1263 struct ice_generic_seg_hdr *seg_hdr; 1264 1265 ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__); 1266 if (!pkg_hdr) 1267 return ICE_ERR_PARAM; 1268 1269 seg_hdr = (struct ice_generic_seg_hdr *) 1270 ice_find_seg_in_pkg(hw, SEGMENT_TYPE_ICE, pkg_hdr); 1271 if (seg_hdr) { 1272 struct ice_meta_sect *meta; 1273 struct ice_pkg_enum state; 1274 1275 ice_memset(&state, 0, sizeof(state), ICE_NONDMA_MEM); 1276 1277 /* Get package information from the Metadata Section */ 1278 meta = (struct ice_meta_sect *) 1279 ice_pkg_enum_section((struct ice_seg *)seg_hdr, &state, 1280 ICE_SID_METADATA); 1281 if (!meta) { 1282 ice_debug(hw, ICE_DBG_INIT, "Did not find ice metadata section in package\n"); 1283 return ICE_ERR_CFG; 1284 } 1285 1286 hw->pkg_ver = meta->ver; 1287 ice_memcpy(hw->pkg_name, meta->name, sizeof(meta->name), 1288 ICE_NONDMA_TO_NONDMA); 1289 1290 ice_debug(hw, ICE_DBG_PKG, "Pkg: %d.%d.%d.%d, %s\n", 1291 meta->ver.major, meta->ver.minor, meta->ver.update, 1292 meta->ver.draft, meta->name); 1293 1294 hw->ice_seg_fmt_ver = seg_hdr->seg_format_ver; 1295 ice_memcpy(hw->ice_seg_id, seg_hdr->seg_id, 1296 sizeof(hw->ice_seg_id), ICE_NONDMA_TO_NONDMA); 1297 1298 ice_debug(hw, ICE_DBG_PKG, "Ice Seg: %d.%d.%d.%d, %s\n", 1299 seg_hdr->seg_format_ver.major, 1300 seg_hdr->seg_format_ver.minor, 1301 seg_hdr->seg_format_ver.update, 1302 seg_hdr->seg_format_ver.draft, 1303 seg_hdr->seg_id); 1304 } else { 1305 ice_debug(hw, ICE_DBG_INIT, "Did not find ice segment in driver package\n"); 1306 return ICE_ERR_CFG; 1307 } 1308 1309 return ICE_SUCCESS; 1310 } 1311 1312 /** 1313 * ice_get_pkg_info 1314 * @hw: pointer to the hardware structure 1315 * 1316 * Store details of the package currently loaded in HW into the HW structure. 1317 */ 1318 static enum ice_status ice_get_pkg_info(struct ice_hw *hw) 1319 { 1320 struct ice_aqc_get_pkg_info_resp *pkg_info; 1321 enum ice_status status; 1322 u16 size; 1323 u32 i; 1324 1325 ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__); 1326 1327 size = ice_struct_size(pkg_info, pkg_info, ICE_PKG_CNT); 1328 pkg_info = (struct ice_aqc_get_pkg_info_resp *)ice_malloc(hw, size); 1329 if (!pkg_info) 1330 return ICE_ERR_NO_MEMORY; 1331 1332 status = ice_aq_get_pkg_info_list(hw, pkg_info, size, NULL); 1333 if (status) 1334 goto init_pkg_free_alloc; 1335 1336 for (i = 0; i < LE32_TO_CPU(pkg_info->count); i++) { 1337 #define ICE_PKG_FLAG_COUNT 4 1338 char flags[ICE_PKG_FLAG_COUNT + 1] = { 0 }; 1339 u8 place = 0; 1340 1341 if (pkg_info->pkg_info[i].is_active) { 1342 flags[place++] = 'A'; 1343 hw->active_pkg_ver = pkg_info->pkg_info[i].ver; 1344 hw->active_track_id = 1345 LE32_TO_CPU(pkg_info->pkg_info[i].track_id); 1346 ice_memcpy(hw->active_pkg_name, 1347 pkg_info->pkg_info[i].name, 1348 sizeof(pkg_info->pkg_info[i].name), 1349 ICE_NONDMA_TO_NONDMA); 1350 hw->active_pkg_in_nvm = pkg_info->pkg_info[i].is_in_nvm; 1351 } 1352 if (pkg_info->pkg_info[i].is_active_at_boot) 1353 flags[place++] = 'B'; 1354 if (pkg_info->pkg_info[i].is_modified) 1355 flags[place++] = 'M'; 1356 if (pkg_info->pkg_info[i].is_in_nvm) 1357 flags[place++] = 'N'; 1358 1359 ice_debug(hw, ICE_DBG_PKG, "Pkg[%d]: %d.%d.%d.%d,%s,%s\n", 1360 i, pkg_info->pkg_info[i].ver.major, 1361 pkg_info->pkg_info[i].ver.minor, 1362 pkg_info->pkg_info[i].ver.update, 1363 pkg_info->pkg_info[i].ver.draft, 1364 pkg_info->pkg_info[i].name, flags); 1365 } 1366 1367 init_pkg_free_alloc: 1368 ice_free(hw, pkg_info); 1369 1370 return status; 1371 } 1372 1373 /** 1374 * ice_verify_pkg - verify package 1375 * @pkg: pointer to the package buffer 1376 * @len: size of the package buffer 1377 * 1378 * Verifies various attributes of the package file, including length, format 1379 * version, and the requirement of at least one segment. 1380 */ 1381 static enum ice_status ice_verify_pkg(struct ice_pkg_hdr *pkg, u32 len) 1382 { 1383 u32 seg_count; 1384 u32 i; 1385 1386 if (len < ice_struct_size(pkg, seg_offset, 1)) 1387 return ICE_ERR_BUF_TOO_SHORT; 1388 1389 if (pkg->pkg_format_ver.major != ICE_PKG_FMT_VER_MAJ || 1390 pkg->pkg_format_ver.minor != ICE_PKG_FMT_VER_MNR || 1391 pkg->pkg_format_ver.update != ICE_PKG_FMT_VER_UPD || 1392 pkg->pkg_format_ver.draft != ICE_PKG_FMT_VER_DFT) 1393 return ICE_ERR_CFG; 1394 1395 /* pkg must have at least one segment */ 1396 seg_count = LE32_TO_CPU(pkg->seg_count); 1397 if (seg_count < 1) 1398 return ICE_ERR_CFG; 1399 1400 /* make sure segment array fits in package length */ 1401 if (len < ice_struct_size(pkg, seg_offset, seg_count)) 1402 return ICE_ERR_BUF_TOO_SHORT; 1403 1404 /* all segments must fit within length */ 1405 for (i = 0; i < seg_count; i++) { 1406 u32 off = LE32_TO_CPU(pkg->seg_offset[i]); 1407 struct ice_generic_seg_hdr *seg; 1408 1409 /* segment header must fit */ 1410 if (len < off + sizeof(*seg)) 1411 return ICE_ERR_BUF_TOO_SHORT; 1412 1413 seg = (struct ice_generic_seg_hdr *)((u8 *)pkg + off); 1414 1415 /* segment body must fit */ 1416 if (len < off + LE32_TO_CPU(seg->seg_size)) 1417 return ICE_ERR_BUF_TOO_SHORT; 1418 } 1419 1420 return ICE_SUCCESS; 1421 } 1422 1423 /** 1424 * ice_free_seg - free package segment pointer 1425 * @hw: pointer to the hardware structure 1426 * 1427 * Frees the package segment pointer in the proper manner, depending on if the 1428 * segment was allocated or just the passed in pointer was stored. 1429 */ 1430 void ice_free_seg(struct ice_hw *hw) 1431 { 1432 if (hw->pkg_copy) { 1433 ice_free(hw, hw->pkg_copy); 1434 hw->pkg_copy = NULL; 1435 hw->pkg_size = 0; 1436 } 1437 hw->seg = NULL; 1438 } 1439 1440 /** 1441 * ice_init_pkg_regs - initialize additional package registers 1442 * @hw: pointer to the hardware structure 1443 */ 1444 static void ice_init_pkg_regs(struct ice_hw *hw) 1445 { 1446 #define ICE_SW_BLK_INP_MASK_L 0xFFFFFFFF 1447 #define ICE_SW_BLK_INP_MASK_H 0x0000FFFF 1448 #define ICE_SW_BLK_IDX 0 1449 if (hw->dcf_enabled) 1450 return; 1451 1452 /* setup Switch block input mask, which is 48-bits in two parts */ 1453 wr32(hw, GL_PREEXT_L2_PMASK0(ICE_SW_BLK_IDX), ICE_SW_BLK_INP_MASK_L); 1454 wr32(hw, GL_PREEXT_L2_PMASK1(ICE_SW_BLK_IDX), ICE_SW_BLK_INP_MASK_H); 1455 } 1456 1457 /** 1458 * ice_chk_pkg_version - check package version for compatibility with driver 1459 * @pkg_ver: pointer to a version structure to check 1460 * 1461 * Check to make sure that the package about to be downloaded is compatible with 1462 * the driver. To be compatible, the major and minor components of the package 1463 * version must match our ICE_PKG_SUPP_VER_MAJ and ICE_PKG_SUPP_VER_MNR 1464 * definitions. 1465 */ 1466 static enum ice_status ice_chk_pkg_version(struct ice_pkg_ver *pkg_ver) 1467 { 1468 if (pkg_ver->major != ICE_PKG_SUPP_VER_MAJ || 1469 pkg_ver->minor != ICE_PKG_SUPP_VER_MNR) 1470 return ICE_ERR_NOT_SUPPORTED; 1471 1472 return ICE_SUCCESS; 1473 } 1474 1475 /** 1476 * ice_chk_pkg_compat 1477 * @hw: pointer to the hardware structure 1478 * @ospkg: pointer to the package hdr 1479 * @seg: pointer to the package segment hdr 1480 * 1481 * This function checks the package version compatibility with driver and NVM 1482 */ 1483 static enum ice_status 1484 ice_chk_pkg_compat(struct ice_hw *hw, struct ice_pkg_hdr *ospkg, 1485 struct ice_seg **seg) 1486 { 1487 struct ice_aqc_get_pkg_info_resp *pkg; 1488 enum ice_status status; 1489 u16 size; 1490 u32 i; 1491 1492 ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__); 1493 1494 /* Check package version compatibility */ 1495 status = ice_chk_pkg_version(&hw->pkg_ver); 1496 if (status) { 1497 ice_debug(hw, ICE_DBG_INIT, "Package version check failed.\n"); 1498 return status; 1499 } 1500 1501 /* find ICE segment in given package */ 1502 *seg = (struct ice_seg *)ice_find_seg_in_pkg(hw, SEGMENT_TYPE_ICE, 1503 ospkg); 1504 if (!*seg) { 1505 ice_debug(hw, ICE_DBG_INIT, "no ice segment in package.\n"); 1506 return ICE_ERR_CFG; 1507 } 1508 1509 /* Check if FW is compatible with the OS package */ 1510 size = ice_struct_size(pkg, pkg_info, ICE_PKG_CNT); 1511 pkg = (struct ice_aqc_get_pkg_info_resp *)ice_malloc(hw, size); 1512 if (!pkg) 1513 return ICE_ERR_NO_MEMORY; 1514 1515 status = ice_aq_get_pkg_info_list(hw, pkg, size, NULL); 1516 if (status) 1517 goto fw_ddp_compat_free_alloc; 1518 1519 for (i = 0; i < LE32_TO_CPU(pkg->count); i++) { 1520 /* loop till we find the NVM package */ 1521 if (!pkg->pkg_info[i].is_in_nvm) 1522 continue; 1523 if ((*seg)->hdr.seg_format_ver.major != 1524 pkg->pkg_info[i].ver.major || 1525 (*seg)->hdr.seg_format_ver.minor > 1526 pkg->pkg_info[i].ver.minor) { 1527 status = ICE_ERR_FW_DDP_MISMATCH; 1528 ice_debug(hw, ICE_DBG_INIT, "OS package is not compatible with NVM.\n"); 1529 } 1530 /* done processing NVM package so break */ 1531 break; 1532 } 1533 fw_ddp_compat_free_alloc: 1534 ice_free(hw, pkg); 1535 return status; 1536 } 1537 1538 /** 1539 * ice_sw_fv_handler 1540 * @sect_type: section type 1541 * @section: pointer to section 1542 * @index: index of the field vector entry to be returned 1543 * @offset: ptr to variable that receives the offset in the field vector table 1544 * 1545 * This is a callback function that can be passed to ice_pkg_enum_entry. 1546 * This function treats the given section as of type ice_sw_fv_section and 1547 * enumerates offset field. "offset" is an index into the field vector table. 1548 */ 1549 static void * 1550 ice_sw_fv_handler(u32 sect_type, void *section, u32 index, u32 *offset) 1551 { 1552 struct ice_sw_fv_section *fv_section = 1553 (struct ice_sw_fv_section *)section; 1554 1555 if (!section || sect_type != ICE_SID_FLD_VEC_SW) 1556 return NULL; 1557 if (index >= LE16_TO_CPU(fv_section->count)) 1558 return NULL; 1559 if (offset) 1560 /* "index" passed in to this function is relative to a given 1561 * 4k block. To get to the true index into the field vector 1562 * table need to add the relative index to the base_offset 1563 * field of this section 1564 */ 1565 *offset = LE16_TO_CPU(fv_section->base_offset) + index; 1566 return fv_section->fv + index; 1567 } 1568 1569 /** 1570 * ice_get_prof_index_max - get the max profile index for used profile 1571 * @hw: pointer to the HW struct 1572 * 1573 * Calling this function will get the max profile index for used profile 1574 * and store the index number in struct ice_switch_info *switch_info 1575 * in hw for following use. 1576 */ 1577 static int ice_get_prof_index_max(struct ice_hw *hw) 1578 { 1579 u16 prof_index = 0, j, max_prof_index = 0; 1580 struct ice_pkg_enum state; 1581 struct ice_seg *ice_seg; 1582 bool flag = false; 1583 struct ice_fv *fv; 1584 u32 offset; 1585 1586 ice_memset(&state, 0, sizeof(state), ICE_NONDMA_MEM); 1587 1588 if (!hw->seg) 1589 return ICE_ERR_PARAM; 1590 1591 ice_seg = hw->seg; 1592 1593 do { 1594 fv = (struct ice_fv *) 1595 ice_pkg_enum_entry(ice_seg, &state, ICE_SID_FLD_VEC_SW, 1596 &offset, ice_sw_fv_handler); 1597 if (!fv) 1598 break; 1599 ice_seg = NULL; 1600 1601 /* in the profile that not be used, the prot_id is set to 0xff 1602 * and the off is set to 0x1ff for all the field vectors. 1603 */ 1604 for (j = 0; j < hw->blk[ICE_BLK_SW].es.fvw; j++) 1605 if (fv->ew[j].prot_id != ICE_PROT_INVALID || 1606 fv->ew[j].off != ICE_FV_OFFSET_INVAL) 1607 flag = true; 1608 if (flag && prof_index > max_prof_index) 1609 max_prof_index = prof_index; 1610 1611 prof_index++; 1612 flag = false; 1613 } while (fv); 1614 1615 hw->switch_info->max_used_prof_index = max_prof_index; 1616 1617 return ICE_SUCCESS; 1618 } 1619 1620 /** 1621 * ice_init_pkg - initialize/download package 1622 * @hw: pointer to the hardware structure 1623 * @buf: pointer to the package buffer 1624 * @len: size of the package buffer 1625 * 1626 * This function initializes a package. The package contains HW tables 1627 * required to do packet processing. First, the function extracts package 1628 * information such as version. Then it finds the ice configuration segment 1629 * within the package; this function then saves a copy of the segment pointer 1630 * within the supplied package buffer. Next, the function will cache any hints 1631 * from the package, followed by downloading the package itself. Note, that if 1632 * a previous PF driver has already downloaded the package successfully, then 1633 * the current driver will not have to download the package again. 1634 * 1635 * The local package contents will be used to query default behavior and to 1636 * update specific sections of the HW's version of the package (e.g. to update 1637 * the parse graph to understand new protocols). 1638 * 1639 * This function stores a pointer to the package buffer memory, and it is 1640 * expected that the supplied buffer will not be freed immediately. If the 1641 * package buffer needs to be freed, such as when read from a file, use 1642 * ice_copy_and_init_pkg() instead of directly calling ice_init_pkg() in this 1643 * case. 1644 */ 1645 enum ice_status ice_init_pkg(struct ice_hw *hw, u8 *buf, u32 len) 1646 { 1647 struct ice_pkg_hdr *pkg; 1648 enum ice_status status; 1649 struct ice_seg *seg; 1650 1651 if (!buf || !len) 1652 return ICE_ERR_PARAM; 1653 1654 pkg = (struct ice_pkg_hdr *)buf; 1655 status = ice_verify_pkg(pkg, len); 1656 if (status) { 1657 ice_debug(hw, ICE_DBG_INIT, "failed to verify pkg (err: %d)\n", 1658 status); 1659 return status; 1660 } 1661 1662 /* initialize package info */ 1663 status = ice_init_pkg_info(hw, pkg); 1664 if (status) 1665 return status; 1666 1667 /* before downloading the package, check package version for 1668 * compatibility with driver 1669 */ 1670 status = ice_chk_pkg_compat(hw, pkg, &seg); 1671 if (status) 1672 return status; 1673 1674 /* initialize package hints and then download package */ 1675 ice_init_pkg_hints(hw, seg); 1676 status = ice_download_pkg(hw, seg); 1677 if (status == ICE_ERR_AQ_NO_WORK) { 1678 ice_debug(hw, ICE_DBG_INIT, "package previously loaded - no work.\n"); 1679 status = ICE_SUCCESS; 1680 } 1681 1682 /* Get information on the package currently loaded in HW, then make sure 1683 * the driver is compatible with this version. 1684 */ 1685 if (!status) { 1686 status = ice_get_pkg_info(hw); 1687 if (!status) 1688 status = ice_chk_pkg_version(&hw->active_pkg_ver); 1689 } 1690 1691 if (!status) { 1692 hw->seg = seg; 1693 /* on successful package download update other required 1694 * registers to support the package and fill HW tables 1695 * with package content. 1696 */ 1697 ice_init_pkg_regs(hw); 1698 ice_fill_blk_tbls(hw); 1699 ice_fill_hw_ptype(hw); 1700 ice_get_prof_index_max(hw); 1701 } else { 1702 ice_debug(hw, ICE_DBG_INIT, "package load failed, %d\n", 1703 status); 1704 } 1705 1706 return status; 1707 } 1708 1709 /** 1710 * ice_copy_and_init_pkg - initialize/download a copy of the package 1711 * @hw: pointer to the hardware structure 1712 * @buf: pointer to the package buffer 1713 * @len: size of the package buffer 1714 * 1715 * This function copies the package buffer, and then calls ice_init_pkg() to 1716 * initialize the copied package contents. 1717 * 1718 * The copying is necessary if the package buffer supplied is constant, or if 1719 * the memory may disappear shortly after calling this function. 1720 * 1721 * If the package buffer resides in the data segment and can be modified, the 1722 * caller is free to use ice_init_pkg() instead of ice_copy_and_init_pkg(). 1723 * 1724 * However, if the package buffer needs to be copied first, such as when being 1725 * read from a file, the caller should use ice_copy_and_init_pkg(). 1726 * 1727 * This function will first copy the package buffer, before calling 1728 * ice_init_pkg(). The caller is free to immediately destroy the original 1729 * package buffer, as the new copy will be managed by this function and 1730 * related routines. 1731 */ 1732 enum ice_status ice_copy_and_init_pkg(struct ice_hw *hw, const u8 *buf, u32 len) 1733 { 1734 enum ice_status status; 1735 u8 *buf_copy; 1736 1737 if (!buf || !len) 1738 return ICE_ERR_PARAM; 1739 1740 buf_copy = (u8 *)ice_memdup(hw, buf, len, ICE_NONDMA_TO_NONDMA); 1741 1742 status = ice_init_pkg(hw, buf_copy, len); 1743 if (status) { 1744 /* Free the copy, since we failed to initialize the package */ 1745 ice_free(hw, buf_copy); 1746 } else { 1747 /* Track the copied pkg so we can free it later */ 1748 hw->pkg_copy = buf_copy; 1749 hw->pkg_size = len; 1750 } 1751 1752 return status; 1753 } 1754 1755 /** 1756 * ice_pkg_buf_alloc 1757 * @hw: pointer to the HW structure 1758 * 1759 * Allocates a package buffer and returns a pointer to the buffer header. 1760 * Note: all package contents must be in Little Endian form. 1761 */ 1762 static struct ice_buf_build *ice_pkg_buf_alloc(struct ice_hw *hw) 1763 { 1764 struct ice_buf_build *bld; 1765 struct ice_buf_hdr *buf; 1766 1767 bld = (struct ice_buf_build *)ice_malloc(hw, sizeof(*bld)); 1768 if (!bld) 1769 return NULL; 1770 1771 buf = (struct ice_buf_hdr *)bld; 1772 buf->data_end = CPU_TO_LE16(offsetof(struct ice_buf_hdr, 1773 section_entry)); 1774 return bld; 1775 } 1776 1777 /** 1778 * ice_get_sw_prof_type - determine switch profile type 1779 * @hw: pointer to the HW structure 1780 * @fv: pointer to the switch field vector 1781 */ 1782 static enum ice_prof_type 1783 ice_get_sw_prof_type(struct ice_hw *hw, struct ice_fv *fv) 1784 { 1785 u16 i; 1786 1787 for (i = 0; i < hw->blk[ICE_BLK_SW].es.fvw; i++) { 1788 /* UDP tunnel will have UDP_OF protocol ID and VNI offset */ 1789 if (fv->ew[i].prot_id == (u8)ICE_PROT_UDP_OF && 1790 fv->ew[i].off == ICE_VNI_OFFSET) 1791 return ICE_PROF_TUN_UDP; 1792 1793 /* GRE tunnel will have GRE protocol */ 1794 if (fv->ew[i].prot_id == (u8)ICE_PROT_GRE_OF) 1795 return ICE_PROF_TUN_GRE; 1796 1797 /* PPPOE tunnel will have PPPOE protocol */ 1798 if (fv->ew[i].prot_id == (u8)ICE_PROT_PPPOE) 1799 return ICE_PROF_TUN_PPPOE; 1800 } 1801 1802 return ICE_PROF_NON_TUN; 1803 } 1804 1805 /** 1806 * ice_get_sw_fv_bitmap - Get switch field vector bitmap based on profile type 1807 * @hw: pointer to hardware structure 1808 * @req_profs: type of profiles requested 1809 * @bm: pointer to memory for returning the bitmap of field vectors 1810 */ 1811 void 1812 ice_get_sw_fv_bitmap(struct ice_hw *hw, enum ice_prof_type req_profs, 1813 ice_bitmap_t *bm) 1814 { 1815 struct ice_pkg_enum state; 1816 struct ice_seg *ice_seg; 1817 struct ice_fv *fv; 1818 1819 if (req_profs == ICE_PROF_ALL) { 1820 ice_bitmap_set(bm, 0, ICE_MAX_NUM_PROFILES); 1821 return; 1822 } 1823 1824 ice_memset(&state, 0, sizeof(state), ICE_NONDMA_MEM); 1825 ice_zero_bitmap(bm, ICE_MAX_NUM_PROFILES); 1826 ice_seg = hw->seg; 1827 do { 1828 enum ice_prof_type prof_type; 1829 u32 offset; 1830 1831 fv = (struct ice_fv *) 1832 ice_pkg_enum_entry(ice_seg, &state, ICE_SID_FLD_VEC_SW, 1833 &offset, ice_sw_fv_handler); 1834 ice_seg = NULL; 1835 1836 if (fv) { 1837 /* Determine field vector type */ 1838 prof_type = ice_get_sw_prof_type(hw, fv); 1839 1840 if (req_profs & prof_type) 1841 ice_set_bit((u16)offset, bm); 1842 } 1843 } while (fv); 1844 } 1845 1846 /** 1847 * ice_get_sw_fv_list 1848 * @hw: pointer to the HW structure 1849 * @prot_ids: field vector to search for with a given protocol ID 1850 * @ids_cnt: lookup/protocol count 1851 * @bm: bitmap of field vectors to consider 1852 * @fv_list: Head of a list 1853 * 1854 * Finds all the field vector entries from switch block that contain 1855 * a given protocol ID and returns a list of structures of type 1856 * "ice_sw_fv_list_entry". Every structure in the list has a field vector 1857 * definition and profile ID information 1858 * NOTE: The caller of the function is responsible for freeing the memory 1859 * allocated for every list entry. 1860 */ 1861 enum ice_status 1862 ice_get_sw_fv_list(struct ice_hw *hw, u8 *prot_ids, u16 ids_cnt, 1863 ice_bitmap_t *bm, struct LIST_HEAD_TYPE *fv_list) 1864 { 1865 struct ice_sw_fv_list_entry *fvl; 1866 struct ice_sw_fv_list_entry *tmp; 1867 struct ice_pkg_enum state; 1868 struct ice_seg *ice_seg; 1869 struct ice_fv *fv; 1870 u32 offset; 1871 1872 ice_memset(&state, 0, sizeof(state), ICE_NONDMA_MEM); 1873 1874 if (!ids_cnt || !hw->seg) 1875 return ICE_ERR_PARAM; 1876 1877 ice_seg = hw->seg; 1878 do { 1879 u16 i; 1880 1881 fv = (struct ice_fv *) 1882 ice_pkg_enum_entry(ice_seg, &state, ICE_SID_FLD_VEC_SW, 1883 &offset, ice_sw_fv_handler); 1884 if (!fv) 1885 break; 1886 ice_seg = NULL; 1887 1888 /* If field vector is not in the bitmap list, then skip this 1889 * profile. 1890 */ 1891 if (!ice_is_bit_set(bm, (u16)offset)) 1892 continue; 1893 1894 for (i = 0; i < ids_cnt; i++) { 1895 int j; 1896 1897 /* This code assumes that if a switch field vector line 1898 * has a matching protocol, then this line will contain 1899 * the entries necessary to represent every field in 1900 * that protocol header. 1901 */ 1902 for (j = 0; j < hw->blk[ICE_BLK_SW].es.fvw; j++) 1903 if (fv->ew[j].prot_id == prot_ids[i]) 1904 break; 1905 if (j >= hw->blk[ICE_BLK_SW].es.fvw) 1906 break; 1907 if (i + 1 == ids_cnt) { 1908 fvl = (struct ice_sw_fv_list_entry *) 1909 ice_malloc(hw, sizeof(*fvl)); 1910 if (!fvl) 1911 goto err; 1912 fvl->fv_ptr = fv; 1913 fvl->profile_id = offset; 1914 LIST_ADD(&fvl->list_entry, fv_list); 1915 break; 1916 } 1917 } 1918 } while (fv); 1919 if (LIST_EMPTY(fv_list)) 1920 return ICE_ERR_CFG; 1921 return ICE_SUCCESS; 1922 1923 err: 1924 LIST_FOR_EACH_ENTRY_SAFE(fvl, tmp, fv_list, ice_sw_fv_list_entry, 1925 list_entry) { 1926 LIST_DEL(&fvl->list_entry); 1927 ice_free(hw, fvl); 1928 } 1929 1930 return ICE_ERR_NO_MEMORY; 1931 } 1932 1933 /** 1934 * ice_init_prof_result_bm - Initialize the profile result index bitmap 1935 * @hw: pointer to hardware structure 1936 */ 1937 void ice_init_prof_result_bm(struct ice_hw *hw) 1938 { 1939 struct ice_pkg_enum state; 1940 struct ice_seg *ice_seg; 1941 struct ice_fv *fv; 1942 1943 ice_memset(&state, 0, sizeof(state), ICE_NONDMA_MEM); 1944 1945 if (!hw->seg) 1946 return; 1947 1948 ice_seg = hw->seg; 1949 do { 1950 u32 off; 1951 u16 i; 1952 1953 fv = (struct ice_fv *) 1954 ice_pkg_enum_entry(ice_seg, &state, ICE_SID_FLD_VEC_SW, 1955 &off, ice_sw_fv_handler); 1956 ice_seg = NULL; 1957 if (!fv) 1958 break; 1959 1960 ice_zero_bitmap(hw->switch_info->prof_res_bm[off], 1961 ICE_MAX_FV_WORDS); 1962 1963 /* Determine empty field vector indices, these can be 1964 * used for recipe results. Skip index 0, since it is 1965 * always used for Switch ID. 1966 */ 1967 for (i = 1; i < ICE_MAX_FV_WORDS; i++) 1968 if (fv->ew[i].prot_id == ICE_PROT_INVALID && 1969 fv->ew[i].off == ICE_FV_OFFSET_INVAL) 1970 ice_set_bit(i, 1971 hw->switch_info->prof_res_bm[off]); 1972 } while (fv); 1973 } 1974 1975 /** 1976 * ice_pkg_buf_free 1977 * @hw: pointer to the HW structure 1978 * @bld: pointer to pkg build (allocated by ice_pkg_buf_alloc()) 1979 * 1980 * Frees a package buffer 1981 */ 1982 void ice_pkg_buf_free(struct ice_hw *hw, struct ice_buf_build *bld) 1983 { 1984 ice_free(hw, bld); 1985 } 1986 1987 /** 1988 * ice_pkg_buf_reserve_section 1989 * @bld: pointer to pkg build (allocated by ice_pkg_buf_alloc()) 1990 * @count: the number of sections to reserve 1991 * 1992 * Reserves one or more section table entries in a package buffer. This routine 1993 * can be called multiple times as long as they are made before calling 1994 * ice_pkg_buf_alloc_section(). Once ice_pkg_buf_alloc_section() 1995 * is called once, the number of sections that can be allocated will not be able 1996 * to be increased; not using all reserved sections is fine, but this will 1997 * result in some wasted space in the buffer. 1998 * Note: all package contents must be in Little Endian form. 1999 */ 2000 static enum ice_status 2001 ice_pkg_buf_reserve_section(struct ice_buf_build *bld, u16 count) 2002 { 2003 struct ice_buf_hdr *buf; 2004 u16 section_count; 2005 u16 data_end; 2006 2007 if (!bld) 2008 return ICE_ERR_PARAM; 2009 2010 buf = (struct ice_buf_hdr *)&bld->buf; 2011 2012 /* already an active section, can't increase table size */ 2013 section_count = LE16_TO_CPU(buf->section_count); 2014 if (section_count > 0) 2015 return ICE_ERR_CFG; 2016 2017 if (bld->reserved_section_table_entries + count > ICE_MAX_S_COUNT) 2018 return ICE_ERR_CFG; 2019 bld->reserved_section_table_entries += count; 2020 2021 data_end = LE16_TO_CPU(buf->data_end) + 2022 FLEX_ARRAY_SIZE(buf, section_entry, count); 2023 buf->data_end = CPU_TO_LE16(data_end); 2024 2025 return ICE_SUCCESS; 2026 } 2027 2028 /** 2029 * ice_pkg_buf_alloc_section 2030 * @bld: pointer to pkg build (allocated by ice_pkg_buf_alloc()) 2031 * @type: the section type value 2032 * @size: the size of the section to reserve (in bytes) 2033 * 2034 * Reserves memory in the buffer for a section's content and updates the 2035 * buffers' status accordingly. This routine returns a pointer to the first 2036 * byte of the section start within the buffer, which is used to fill in the 2037 * section contents. 2038 * Note: all package contents must be in Little Endian form. 2039 */ 2040 static void * 2041 ice_pkg_buf_alloc_section(struct ice_buf_build *bld, u32 type, u16 size) 2042 { 2043 struct ice_buf_hdr *buf; 2044 u16 sect_count; 2045 u16 data_end; 2046 2047 if (!bld || !type || !size) 2048 return NULL; 2049 2050 buf = (struct ice_buf_hdr *)&bld->buf; 2051 2052 /* check for enough space left in buffer */ 2053 data_end = LE16_TO_CPU(buf->data_end); 2054 2055 /* section start must align on 4 byte boundary */ 2056 data_end = ICE_ALIGN(data_end, 4); 2057 2058 if ((data_end + size) > ICE_MAX_S_DATA_END) 2059 return NULL; 2060 2061 /* check for more available section table entries */ 2062 sect_count = LE16_TO_CPU(buf->section_count); 2063 if (sect_count < bld->reserved_section_table_entries) { 2064 void *section_ptr = ((u8 *)buf) + data_end; 2065 2066 buf->section_entry[sect_count].offset = CPU_TO_LE16(data_end); 2067 buf->section_entry[sect_count].size = CPU_TO_LE16(size); 2068 buf->section_entry[sect_count].type = CPU_TO_LE32(type); 2069 2070 data_end += size; 2071 buf->data_end = CPU_TO_LE16(data_end); 2072 2073 buf->section_count = CPU_TO_LE16(sect_count + 1); 2074 return section_ptr; 2075 } 2076 2077 /* no free section table entries */ 2078 return NULL; 2079 } 2080 2081 /** 2082 * ice_pkg_buf_alloc_single_section 2083 * @hw: pointer to the HW structure 2084 * @type: the section type value 2085 * @size: the size of the section to reserve (in bytes) 2086 * @section: returns pointer to the section 2087 * 2088 * Allocates a package buffer with a single section. 2089 * Note: all package contents must be in Little Endian form. 2090 */ 2091 struct ice_buf_build * 2092 ice_pkg_buf_alloc_single_section(struct ice_hw *hw, u32 type, u16 size, 2093 void **section) 2094 { 2095 struct ice_buf_build *buf; 2096 2097 if (!section) 2098 return NULL; 2099 2100 buf = ice_pkg_buf_alloc(hw); 2101 if (!buf) 2102 return NULL; 2103 2104 if (ice_pkg_buf_reserve_section(buf, 1)) 2105 goto ice_pkg_buf_alloc_single_section_err; 2106 2107 *section = ice_pkg_buf_alloc_section(buf, type, size); 2108 if (!*section) 2109 goto ice_pkg_buf_alloc_single_section_err; 2110 2111 return buf; 2112 2113 ice_pkg_buf_alloc_single_section_err: 2114 ice_pkg_buf_free(hw, buf); 2115 return NULL; 2116 } 2117 2118 /** 2119 * ice_pkg_buf_get_active_sections 2120 * @bld: pointer to pkg build (allocated by ice_pkg_buf_alloc()) 2121 * 2122 * Returns the number of active sections. Before using the package buffer 2123 * in an update package command, the caller should make sure that there is at 2124 * least one active section - otherwise, the buffer is not legal and should 2125 * not be used. 2126 * Note: all package contents must be in Little Endian form. 2127 */ 2128 static u16 ice_pkg_buf_get_active_sections(struct ice_buf_build *bld) 2129 { 2130 struct ice_buf_hdr *buf; 2131 2132 if (!bld) 2133 return 0; 2134 2135 buf = (struct ice_buf_hdr *)&bld->buf; 2136 return LE16_TO_CPU(buf->section_count); 2137 } 2138 2139 /** 2140 * ice_pkg_buf 2141 * @bld: pointer to pkg build (allocated by ice_pkg_buf_alloc()) 2142 * 2143 * Return a pointer to the buffer's header 2144 */ 2145 struct ice_buf *ice_pkg_buf(struct ice_buf_build *bld) 2146 { 2147 if (!bld) 2148 return NULL; 2149 2150 return &bld->buf; 2151 } 2152 2153 /** 2154 * ice_tunnel_port_in_use_hlpr - helper function to determine tunnel usage 2155 * @hw: pointer to the HW structure 2156 * @port: port to search for 2157 * @index: optionally returns index 2158 * 2159 * Returns whether a port is already in use as a tunnel, and optionally its 2160 * index 2161 */ 2162 static bool ice_tunnel_port_in_use_hlpr(struct ice_hw *hw, u16 port, u16 *index) 2163 { 2164 u16 i; 2165 2166 for (i = 0; i < hw->tnl.count && i < ICE_TUNNEL_MAX_ENTRIES; i++) 2167 if (hw->tnl.tbl[i].in_use && hw->tnl.tbl[i].port == port) { 2168 if (index) 2169 *index = i; 2170 return true; 2171 } 2172 2173 return false; 2174 } 2175 2176 /** 2177 * ice_tunnel_port_in_use 2178 * @hw: pointer to the HW structure 2179 * @port: port to search for 2180 * @index: optionally returns index 2181 * 2182 * Returns whether a port is already in use as a tunnel, and optionally its 2183 * index 2184 */ 2185 bool ice_tunnel_port_in_use(struct ice_hw *hw, u16 port, u16 *index) 2186 { 2187 bool res; 2188 2189 ice_acquire_lock(&hw->tnl_lock); 2190 res = ice_tunnel_port_in_use_hlpr(hw, port, index); 2191 ice_release_lock(&hw->tnl_lock); 2192 2193 return res; 2194 } 2195 2196 /** 2197 * ice_tunnel_get_type 2198 * @hw: pointer to the HW structure 2199 * @port: port to search for 2200 * @type: returns tunnel index 2201 * 2202 * For a given port number, will return the type of tunnel. 2203 */ 2204 bool 2205 ice_tunnel_get_type(struct ice_hw *hw, u16 port, enum ice_tunnel_type *type) 2206 { 2207 bool res = false; 2208 u16 i; 2209 2210 ice_acquire_lock(&hw->tnl_lock); 2211 2212 for (i = 0; i < hw->tnl.count && i < ICE_TUNNEL_MAX_ENTRIES; i++) 2213 if (hw->tnl.tbl[i].in_use && hw->tnl.tbl[i].port == port) { 2214 *type = hw->tnl.tbl[i].type; 2215 res = true; 2216 break; 2217 } 2218 2219 ice_release_lock(&hw->tnl_lock); 2220 2221 return res; 2222 } 2223 2224 /** 2225 * ice_find_free_tunnel_entry 2226 * @hw: pointer to the HW structure 2227 * @type: tunnel type 2228 * @index: optionally returns index 2229 * 2230 * Returns whether there is a free tunnel entry, and optionally its index 2231 */ 2232 static bool 2233 ice_find_free_tunnel_entry(struct ice_hw *hw, enum ice_tunnel_type type, 2234 u16 *index) 2235 { 2236 u16 i; 2237 2238 for (i = 0; i < hw->tnl.count && i < ICE_TUNNEL_MAX_ENTRIES; i++) 2239 if (hw->tnl.tbl[i].valid && !hw->tnl.tbl[i].in_use && 2240 hw->tnl.tbl[i].type == type) { 2241 if (index) 2242 *index = i; 2243 return true; 2244 } 2245 2246 return false; 2247 } 2248 2249 /** 2250 * ice_get_open_tunnel_port - retrieve an open tunnel port 2251 * @hw: pointer to the HW structure 2252 * @type: tunnel type (TNL_ALL will return any open port) 2253 * @port: returns open port 2254 */ 2255 bool 2256 ice_get_open_tunnel_port(struct ice_hw *hw, enum ice_tunnel_type type, 2257 u16 *port) 2258 { 2259 bool res = false; 2260 u16 i; 2261 2262 ice_acquire_lock(&hw->tnl_lock); 2263 2264 for (i = 0; i < hw->tnl.count && i < ICE_TUNNEL_MAX_ENTRIES; i++) 2265 if (hw->tnl.tbl[i].valid && hw->tnl.tbl[i].in_use && 2266 (type == TNL_ALL || hw->tnl.tbl[i].type == type)) { 2267 *port = hw->tnl.tbl[i].port; 2268 res = true; 2269 break; 2270 } 2271 2272 ice_release_lock(&hw->tnl_lock); 2273 2274 return res; 2275 } 2276 2277 /** 2278 * ice_upd_dvm_boost_entry 2279 * @hw: pointer to the HW structure 2280 * @entry: pointer to double vlan boost entry info 2281 */ 2282 static enum ice_status 2283 ice_upd_dvm_boost_entry(struct ice_hw *hw, struct ice_dvm_entry *entry) 2284 { 2285 struct ice_boost_tcam_section *sect_rx, *sect_tx; 2286 enum ice_status status = ICE_ERR_MAX_LIMIT; 2287 struct ice_buf_build *bld; 2288 u8 val, dc, nm; 2289 2290 bld = ice_pkg_buf_alloc(hw); 2291 if (!bld) 2292 return ICE_ERR_NO_MEMORY; 2293 2294 /* allocate 2 sections, one for Rx parser, one for Tx parser */ 2295 if (ice_pkg_buf_reserve_section(bld, 2)) 2296 goto ice_upd_dvm_boost_entry_err; 2297 2298 sect_rx = (struct ice_boost_tcam_section *) 2299 ice_pkg_buf_alloc_section(bld, ICE_SID_RXPARSER_BOOST_TCAM, 2300 ice_struct_size(sect_rx, tcam, 1)); 2301 if (!sect_rx) 2302 goto ice_upd_dvm_boost_entry_err; 2303 sect_rx->count = CPU_TO_LE16(1); 2304 2305 sect_tx = (struct ice_boost_tcam_section *) 2306 ice_pkg_buf_alloc_section(bld, ICE_SID_TXPARSER_BOOST_TCAM, 2307 ice_struct_size(sect_tx, tcam, 1)); 2308 if (!sect_tx) 2309 goto ice_upd_dvm_boost_entry_err; 2310 sect_tx->count = CPU_TO_LE16(1); 2311 2312 /* copy original boost entry to update package buffer */ 2313 ice_memcpy(sect_rx->tcam, entry->boost_entry, sizeof(*sect_rx->tcam), 2314 ICE_NONDMA_TO_NONDMA); 2315 2316 /* re-write the don't care and never match bits accordingly */ 2317 if (entry->enable) { 2318 /* all bits are don't care */ 2319 val = 0x00; 2320 dc = 0xFF; 2321 nm = 0x00; 2322 } else { 2323 /* disable, one never match bit, the rest are don't care */ 2324 val = 0x00; 2325 dc = 0xF7; 2326 nm = 0x08; 2327 } 2328 2329 ice_set_key((u8 *)§_rx->tcam[0].key, sizeof(sect_rx->tcam[0].key), 2330 &val, NULL, &dc, &nm, 0, sizeof(u8)); 2331 2332 /* exact copy of entry to Tx section entry */ 2333 ice_memcpy(sect_tx->tcam, sect_rx->tcam, sizeof(*sect_tx->tcam), 2334 ICE_NONDMA_TO_NONDMA); 2335 2336 status = ice_update_pkg_no_lock(hw, ice_pkg_buf(bld), 1); 2337 2338 ice_upd_dvm_boost_entry_err: 2339 ice_pkg_buf_free(hw, bld); 2340 2341 return status; 2342 } 2343 2344 /** 2345 * ice_set_dvm_boost_entries 2346 * @hw: pointer to the HW structure 2347 * 2348 * Enable double vlan by updating the appropriate boost tcam entries. 2349 */ 2350 enum ice_status ice_set_dvm_boost_entries(struct ice_hw *hw) 2351 { 2352 enum ice_status status; 2353 u16 i; 2354 2355 for (i = 0; i < hw->dvm_upd.count; i++) { 2356 status = ice_upd_dvm_boost_entry(hw, &hw->dvm_upd.tbl[i]); 2357 if (status) 2358 return status; 2359 } 2360 2361 return ICE_SUCCESS; 2362 } 2363 2364 /** 2365 * ice_create_tunnel 2366 * @hw: pointer to the HW structure 2367 * @type: type of tunnel 2368 * @port: port of tunnel to create 2369 * 2370 * Create a tunnel by updating the parse graph in the parser. We do that by 2371 * creating a package buffer with the tunnel info and issuing an update package 2372 * command. 2373 */ 2374 enum ice_status 2375 ice_create_tunnel(struct ice_hw *hw, enum ice_tunnel_type type, u16 port) 2376 { 2377 struct ice_boost_tcam_section *sect_rx, *sect_tx; 2378 enum ice_status status = ICE_ERR_MAX_LIMIT; 2379 struct ice_buf_build *bld; 2380 u16 index; 2381 2382 ice_acquire_lock(&hw->tnl_lock); 2383 2384 if (ice_tunnel_port_in_use_hlpr(hw, port, &index)) { 2385 hw->tnl.tbl[index].ref++; 2386 status = ICE_SUCCESS; 2387 goto ice_create_tunnel_end; 2388 } 2389 2390 if (!ice_find_free_tunnel_entry(hw, type, &index)) { 2391 status = ICE_ERR_OUT_OF_RANGE; 2392 goto ice_create_tunnel_end; 2393 } 2394 2395 bld = ice_pkg_buf_alloc(hw); 2396 if (!bld) { 2397 status = ICE_ERR_NO_MEMORY; 2398 goto ice_create_tunnel_end; 2399 } 2400 2401 /* allocate 2 sections, one for Rx parser, one for Tx parser */ 2402 if (ice_pkg_buf_reserve_section(bld, 2)) 2403 goto ice_create_tunnel_err; 2404 2405 sect_rx = (struct ice_boost_tcam_section *) 2406 ice_pkg_buf_alloc_section(bld, ICE_SID_RXPARSER_BOOST_TCAM, 2407 ice_struct_size(sect_rx, tcam, 1)); 2408 if (!sect_rx) 2409 goto ice_create_tunnel_err; 2410 sect_rx->count = CPU_TO_LE16(1); 2411 2412 sect_tx = (struct ice_boost_tcam_section *) 2413 ice_pkg_buf_alloc_section(bld, ICE_SID_TXPARSER_BOOST_TCAM, 2414 ice_struct_size(sect_tx, tcam, 1)); 2415 if (!sect_tx) 2416 goto ice_create_tunnel_err; 2417 sect_tx->count = CPU_TO_LE16(1); 2418 2419 /* copy original boost entry to update package buffer */ 2420 ice_memcpy(sect_rx->tcam, hw->tnl.tbl[index].boost_entry, 2421 sizeof(*sect_rx->tcam), ICE_NONDMA_TO_NONDMA); 2422 2423 /* over-write the never-match dest port key bits with the encoded port 2424 * bits 2425 */ 2426 ice_set_key((u8 *)§_rx->tcam[0].key, sizeof(sect_rx->tcam[0].key), 2427 (u8 *)&port, NULL, NULL, NULL, 2428 (u16)offsetof(struct ice_boost_key_value, hv_dst_port_key), 2429 sizeof(sect_rx->tcam[0].key.key.hv_dst_port_key)); 2430 2431 /* exact copy of entry to Tx section entry */ 2432 ice_memcpy(sect_tx->tcam, sect_rx->tcam, sizeof(*sect_tx->tcam), 2433 ICE_NONDMA_TO_NONDMA); 2434 2435 status = ice_update_pkg(hw, ice_pkg_buf(bld), 1); 2436 if (!status) { 2437 hw->tnl.tbl[index].port = port; 2438 hw->tnl.tbl[index].in_use = true; 2439 hw->tnl.tbl[index].ref = 1; 2440 } 2441 2442 ice_create_tunnel_err: 2443 ice_pkg_buf_free(hw, bld); 2444 2445 ice_create_tunnel_end: 2446 ice_release_lock(&hw->tnl_lock); 2447 2448 return status; 2449 } 2450 2451 /** 2452 * ice_destroy_tunnel 2453 * @hw: pointer to the HW structure 2454 * @port: port of tunnel to destroy (ignored if the all parameter is true) 2455 * @all: flag that states to destroy all tunnels 2456 * 2457 * Destroys a tunnel or all tunnels by creating an update package buffer 2458 * targeting the specific updates requested and then performing an update 2459 * package. 2460 */ 2461 enum ice_status ice_destroy_tunnel(struct ice_hw *hw, u16 port, bool all) 2462 { 2463 struct ice_boost_tcam_section *sect_rx, *sect_tx; 2464 enum ice_status status = ICE_ERR_MAX_LIMIT; 2465 struct ice_buf_build *bld; 2466 u16 count = 0; 2467 u16 index; 2468 u16 size; 2469 u16 i, j; 2470 2471 ice_acquire_lock(&hw->tnl_lock); 2472 2473 if (!all && ice_tunnel_port_in_use_hlpr(hw, port, &index)) 2474 if (hw->tnl.tbl[index].ref > 1) { 2475 hw->tnl.tbl[index].ref--; 2476 status = ICE_SUCCESS; 2477 goto ice_destroy_tunnel_end; 2478 } 2479 2480 /* determine count */ 2481 for (i = 0; i < hw->tnl.count && i < ICE_TUNNEL_MAX_ENTRIES; i++) 2482 if (hw->tnl.tbl[i].valid && hw->tnl.tbl[i].in_use && 2483 (all || hw->tnl.tbl[i].port == port)) 2484 count++; 2485 2486 if (!count) { 2487 status = ICE_ERR_PARAM; 2488 goto ice_destroy_tunnel_end; 2489 } 2490 2491 /* size of section - there is at least one entry */ 2492 size = ice_struct_size(sect_rx, tcam, count); 2493 2494 bld = ice_pkg_buf_alloc(hw); 2495 if (!bld) { 2496 status = ICE_ERR_NO_MEMORY; 2497 goto ice_destroy_tunnel_end; 2498 } 2499 2500 /* allocate 2 sections, one for Rx parser, one for Tx parser */ 2501 if (ice_pkg_buf_reserve_section(bld, 2)) 2502 goto ice_destroy_tunnel_err; 2503 2504 sect_rx = (struct ice_boost_tcam_section *) 2505 ice_pkg_buf_alloc_section(bld, ICE_SID_RXPARSER_BOOST_TCAM, 2506 size); 2507 if (!sect_rx) 2508 goto ice_destroy_tunnel_err; 2509 sect_rx->count = CPU_TO_LE16(count); 2510 2511 sect_tx = (struct ice_boost_tcam_section *) 2512 ice_pkg_buf_alloc_section(bld, ICE_SID_TXPARSER_BOOST_TCAM, 2513 size); 2514 if (!sect_tx) 2515 goto ice_destroy_tunnel_err; 2516 sect_tx->count = CPU_TO_LE16(count); 2517 2518 /* copy original boost entry to update package buffer, one copy to Rx 2519 * section, another copy to the Tx section 2520 */ 2521 for (i = 0, j = 0; i < hw->tnl.count && i < ICE_TUNNEL_MAX_ENTRIES; i++) 2522 if (hw->tnl.tbl[i].valid && hw->tnl.tbl[i].in_use && 2523 (all || hw->tnl.tbl[i].port == port)) { 2524 ice_memcpy(sect_rx->tcam + j, 2525 hw->tnl.tbl[i].boost_entry, 2526 sizeof(*sect_rx->tcam), 2527 ICE_NONDMA_TO_NONDMA); 2528 ice_memcpy(sect_tx->tcam + j, 2529 hw->tnl.tbl[i].boost_entry, 2530 sizeof(*sect_tx->tcam), 2531 ICE_NONDMA_TO_NONDMA); 2532 hw->tnl.tbl[i].marked = true; 2533 j++; 2534 } 2535 2536 status = ice_update_pkg(hw, ice_pkg_buf(bld), 1); 2537 if (!status) 2538 for (i = 0; i < hw->tnl.count && 2539 i < ICE_TUNNEL_MAX_ENTRIES; i++) 2540 if (hw->tnl.tbl[i].marked) { 2541 hw->tnl.tbl[i].ref = 0; 2542 hw->tnl.tbl[i].port = 0; 2543 hw->tnl.tbl[i].in_use = false; 2544 hw->tnl.tbl[i].marked = false; 2545 } 2546 2547 ice_destroy_tunnel_err: 2548 ice_pkg_buf_free(hw, bld); 2549 2550 ice_destroy_tunnel_end: 2551 ice_release_lock(&hw->tnl_lock); 2552 2553 return status; 2554 } 2555 2556 /** 2557 * ice_find_prot_off - find prot ID and offset pair, based on prof and FV index 2558 * @hw: pointer to the hardware structure 2559 * @blk: hardware block 2560 * @prof: profile ID 2561 * @fv_idx: field vector word index 2562 * @prot: variable to receive the protocol ID 2563 * @off: variable to receive the protocol offset 2564 */ 2565 enum ice_status 2566 ice_find_prot_off(struct ice_hw *hw, enum ice_block blk, u8 prof, u16 fv_idx, 2567 u8 *prot, u16 *off) 2568 { 2569 struct ice_fv_word *fv_ext; 2570 2571 if (prof >= hw->blk[blk].es.count) 2572 return ICE_ERR_PARAM; 2573 2574 if (fv_idx >= hw->blk[blk].es.fvw) 2575 return ICE_ERR_PARAM; 2576 2577 fv_ext = hw->blk[blk].es.t + (prof * hw->blk[blk].es.fvw); 2578 2579 *prot = fv_ext[fv_idx].prot_id; 2580 *off = fv_ext[fv_idx].off; 2581 2582 return ICE_SUCCESS; 2583 } 2584 2585 /* PTG Management */ 2586 2587 /** 2588 * ice_ptg_find_ptype - Search for packet type group using packet type (ptype) 2589 * @hw: pointer to the hardware structure 2590 * @blk: HW block 2591 * @ptype: the ptype to search for 2592 * @ptg: pointer to variable that receives the PTG 2593 * 2594 * This function will search the PTGs for a particular ptype, returning the 2595 * PTG ID that contains it through the PTG parameter, with the value of 2596 * ICE_DEFAULT_PTG (0) meaning it is part the default PTG. 2597 */ 2598 static enum ice_status 2599 ice_ptg_find_ptype(struct ice_hw *hw, enum ice_block blk, u16 ptype, u8 *ptg) 2600 { 2601 if (ptype >= ICE_XLT1_CNT || !ptg) 2602 return ICE_ERR_PARAM; 2603 2604 *ptg = hw->blk[blk].xlt1.ptypes[ptype].ptg; 2605 return ICE_SUCCESS; 2606 } 2607 2608 /** 2609 * ice_ptg_alloc_val - Allocates a new packet type group ID by value 2610 * @hw: pointer to the hardware structure 2611 * @blk: HW block 2612 * @ptg: the PTG to allocate 2613 * 2614 * This function allocates a given packet type group ID specified by the PTG 2615 * parameter. 2616 */ 2617 static void ice_ptg_alloc_val(struct ice_hw *hw, enum ice_block blk, u8 ptg) 2618 { 2619 hw->blk[blk].xlt1.ptg_tbl[ptg].in_use = true; 2620 } 2621 2622 /** 2623 * ice_ptg_remove_ptype - Removes ptype from a particular packet type group 2624 * @hw: pointer to the hardware structure 2625 * @blk: HW block 2626 * @ptype: the ptype to remove 2627 * @ptg: the PTG to remove the ptype from 2628 * 2629 * This function will remove the ptype from the specific PTG, and move it to 2630 * the default PTG (ICE_DEFAULT_PTG). 2631 */ 2632 static enum ice_status 2633 ice_ptg_remove_ptype(struct ice_hw *hw, enum ice_block blk, u16 ptype, u8 ptg) 2634 { 2635 struct ice_ptg_ptype **ch; 2636 struct ice_ptg_ptype *p; 2637 2638 if (ptype > ICE_XLT1_CNT - 1) 2639 return ICE_ERR_PARAM; 2640 2641 if (!hw->blk[blk].xlt1.ptg_tbl[ptg].in_use) 2642 return ICE_ERR_DOES_NOT_EXIST; 2643 2644 /* Should not happen if .in_use is set, bad config */ 2645 if (!hw->blk[blk].xlt1.ptg_tbl[ptg].first_ptype) 2646 return ICE_ERR_CFG; 2647 2648 /* find the ptype within this PTG, and bypass the link over it */ 2649 p = hw->blk[blk].xlt1.ptg_tbl[ptg].first_ptype; 2650 ch = &hw->blk[blk].xlt1.ptg_tbl[ptg].first_ptype; 2651 while (p) { 2652 if (ptype == (p - hw->blk[blk].xlt1.ptypes)) { 2653 *ch = p->next_ptype; 2654 break; 2655 } 2656 2657 ch = &p->next_ptype; 2658 p = p->next_ptype; 2659 } 2660 2661 hw->blk[blk].xlt1.ptypes[ptype].ptg = ICE_DEFAULT_PTG; 2662 hw->blk[blk].xlt1.ptypes[ptype].next_ptype = NULL; 2663 2664 return ICE_SUCCESS; 2665 } 2666 2667 /** 2668 * ice_ptg_add_mv_ptype - Adds/moves ptype to a particular packet type group 2669 * @hw: pointer to the hardware structure 2670 * @blk: HW block 2671 * @ptype: the ptype to add or move 2672 * @ptg: the PTG to add or move the ptype to 2673 * 2674 * This function will either add or move a ptype to a particular PTG depending 2675 * on if the ptype is already part of another group. Note that using a 2676 * a destination PTG ID of ICE_DEFAULT_PTG (0) will move the ptype to the 2677 * default PTG. 2678 */ 2679 static enum ice_status 2680 ice_ptg_add_mv_ptype(struct ice_hw *hw, enum ice_block blk, u16 ptype, u8 ptg) 2681 { 2682 enum ice_status status; 2683 u8 original_ptg; 2684 2685 if (ptype > ICE_XLT1_CNT - 1) 2686 return ICE_ERR_PARAM; 2687 2688 if (!hw->blk[blk].xlt1.ptg_tbl[ptg].in_use && ptg != ICE_DEFAULT_PTG) 2689 return ICE_ERR_DOES_NOT_EXIST; 2690 2691 status = ice_ptg_find_ptype(hw, blk, ptype, &original_ptg); 2692 if (status) 2693 return status; 2694 2695 /* Is ptype already in the correct PTG? */ 2696 if (original_ptg == ptg) 2697 return ICE_SUCCESS; 2698 2699 /* Remove from original PTG and move back to the default PTG */ 2700 if (original_ptg != ICE_DEFAULT_PTG) 2701 ice_ptg_remove_ptype(hw, blk, ptype, original_ptg); 2702 2703 /* Moving to default PTG? Then we're done with this request */ 2704 if (ptg == ICE_DEFAULT_PTG) 2705 return ICE_SUCCESS; 2706 2707 /* Add ptype to PTG at beginning of list */ 2708 hw->blk[blk].xlt1.ptypes[ptype].next_ptype = 2709 hw->blk[blk].xlt1.ptg_tbl[ptg].first_ptype; 2710 hw->blk[blk].xlt1.ptg_tbl[ptg].first_ptype = 2711 &hw->blk[blk].xlt1.ptypes[ptype]; 2712 2713 hw->blk[blk].xlt1.ptypes[ptype].ptg = ptg; 2714 hw->blk[blk].xlt1.t[ptype] = ptg; 2715 2716 return ICE_SUCCESS; 2717 } 2718 2719 /* Block / table size info */ 2720 struct ice_blk_size_details { 2721 u16 xlt1; /* # XLT1 entries */ 2722 u16 xlt2; /* # XLT2 entries */ 2723 u16 prof_tcam; /* # profile ID TCAM entries */ 2724 u16 prof_id; /* # profile IDs */ 2725 u8 prof_cdid_bits; /* # CDID one-hot bits used in key */ 2726 u16 prof_redir; /* # profile redirection entries */ 2727 u16 es; /* # extraction sequence entries */ 2728 u16 fvw; /* # field vector words */ 2729 u8 overwrite; /* overwrite existing entries allowed */ 2730 u8 reverse; /* reverse FV order */ 2731 }; 2732 2733 static const struct ice_blk_size_details blk_sizes[ICE_BLK_COUNT] = { 2734 /** 2735 * Table Definitions 2736 * XLT1 - Number of entries in XLT1 table 2737 * XLT2 - Number of entries in XLT2 table 2738 * TCAM - Number of entries Profile ID TCAM table 2739 * CDID - Control Domain ID of the hardware block 2740 * PRED - Number of entries in the Profile Redirection Table 2741 * FV - Number of entries in the Field Vector 2742 * FVW - Width (in WORDs) of the Field Vector 2743 * OVR - Overwrite existing table entries 2744 * REV - Reverse FV 2745 */ 2746 /* XLT1 , XLT2 ,TCAM, PID,CDID,PRED, FV, FVW */ 2747 /* Overwrite , Reverse FV */ 2748 /* SW */ { ICE_XLT1_CNT, ICE_XLT2_CNT, 512, 256, 0, 256, 256, 48, 2749 false, false }, 2750 /* ACL */ { ICE_XLT1_CNT, ICE_XLT2_CNT, 512, 128, 0, 128, 128, 32, 2751 false, false }, 2752 /* FD */ { ICE_XLT1_CNT, ICE_XLT2_CNT, 512, 128, 0, 128, 128, 24, 2753 false, true }, 2754 /* RSS */ { ICE_XLT1_CNT, ICE_XLT2_CNT, 512, 128, 0, 128, 128, 24, 2755 true, true }, 2756 /* PE */ { ICE_XLT1_CNT, ICE_XLT2_CNT, 64, 32, 0, 32, 32, 24, 2757 false, false }, 2758 }; 2759 2760 enum ice_sid_all { 2761 ICE_SID_XLT1_OFF = 0, 2762 ICE_SID_XLT2_OFF, 2763 ICE_SID_PR_OFF, 2764 ICE_SID_PR_REDIR_OFF, 2765 ICE_SID_ES_OFF, 2766 ICE_SID_OFF_COUNT, 2767 }; 2768 2769 /* Characteristic handling */ 2770 2771 /** 2772 * ice_match_prop_lst - determine if properties of two lists match 2773 * @list1: first properties list 2774 * @list2: second properties list 2775 * 2776 * Count, cookies and the order must match in order to be considered equivalent. 2777 */ 2778 static bool 2779 ice_match_prop_lst(struct LIST_HEAD_TYPE *list1, struct LIST_HEAD_TYPE *list2) 2780 { 2781 struct ice_vsig_prof *tmp1; 2782 struct ice_vsig_prof *tmp2; 2783 u16 chk_count = 0; 2784 u16 count = 0; 2785 2786 /* compare counts */ 2787 LIST_FOR_EACH_ENTRY(tmp1, list1, ice_vsig_prof, list) 2788 count++; 2789 LIST_FOR_EACH_ENTRY(tmp2, list2, ice_vsig_prof, list) 2790 chk_count++; 2791 if (!count || count != chk_count) 2792 return false; 2793 2794 tmp1 = LIST_FIRST_ENTRY(list1, struct ice_vsig_prof, list); 2795 tmp2 = LIST_FIRST_ENTRY(list2, struct ice_vsig_prof, list); 2796 2797 /* profile cookies must compare, and in the exact same order to take 2798 * into account priority 2799 */ 2800 while (count--) { 2801 if (tmp2->profile_cookie != tmp1->profile_cookie) 2802 return false; 2803 2804 tmp1 = LIST_NEXT_ENTRY(tmp1, struct ice_vsig_prof, list); 2805 tmp2 = LIST_NEXT_ENTRY(tmp2, struct ice_vsig_prof, list); 2806 } 2807 2808 return true; 2809 } 2810 2811 /* VSIG Management */ 2812 2813 /** 2814 * ice_vsig_find_vsi - find a VSIG that contains a specified VSI 2815 * @hw: pointer to the hardware structure 2816 * @blk: HW block 2817 * @vsi: VSI of interest 2818 * @vsig: pointer to receive the VSI group 2819 * 2820 * This function will lookup the VSI entry in the XLT2 list and return 2821 * the VSI group its associated with. 2822 */ 2823 enum ice_status 2824 ice_vsig_find_vsi(struct ice_hw *hw, enum ice_block blk, u16 vsi, u16 *vsig) 2825 { 2826 if (!vsig || vsi >= ICE_MAX_VSI) 2827 return ICE_ERR_PARAM; 2828 2829 /* As long as there's a default or valid VSIG associated with the input 2830 * VSI, the functions returns a success. Any handling of VSIG will be 2831 * done by the following add, update or remove functions. 2832 */ 2833 *vsig = hw->blk[blk].xlt2.vsis[vsi].vsig; 2834 2835 return ICE_SUCCESS; 2836 } 2837 2838 /** 2839 * ice_vsig_alloc_val - allocate a new VSIG by value 2840 * @hw: pointer to the hardware structure 2841 * @blk: HW block 2842 * @vsig: the VSIG to allocate 2843 * 2844 * This function will allocate a given VSIG specified by the VSIG parameter. 2845 */ 2846 static u16 ice_vsig_alloc_val(struct ice_hw *hw, enum ice_block blk, u16 vsig) 2847 { 2848 u16 idx = vsig & ICE_VSIG_IDX_M; 2849 2850 if (!hw->blk[blk].xlt2.vsig_tbl[idx].in_use) { 2851 INIT_LIST_HEAD(&hw->blk[blk].xlt2.vsig_tbl[idx].prop_lst); 2852 hw->blk[blk].xlt2.vsig_tbl[idx].in_use = true; 2853 } 2854 2855 return ICE_VSIG_VALUE(idx, hw->pf_id); 2856 } 2857 2858 /** 2859 * ice_vsig_alloc - Finds a free entry and allocates a new VSIG 2860 * @hw: pointer to the hardware structure 2861 * @blk: HW block 2862 * 2863 * This function will iterate through the VSIG list and mark the first 2864 * unused entry for the new VSIG entry as used and return that value. 2865 */ 2866 static u16 ice_vsig_alloc(struct ice_hw *hw, enum ice_block blk) 2867 { 2868 u16 i; 2869 2870 for (i = 1; i < ICE_MAX_VSIGS; i++) 2871 if (!hw->blk[blk].xlt2.vsig_tbl[i].in_use) 2872 return ice_vsig_alloc_val(hw, blk, i); 2873 2874 return ICE_DEFAULT_VSIG; 2875 } 2876 2877 /** 2878 * ice_find_dup_props_vsig - find VSI group with a specified set of properties 2879 * @hw: pointer to the hardware structure 2880 * @blk: HW block 2881 * @chs: characteristic list 2882 * @vsig: returns the VSIG with the matching profiles, if found 2883 * 2884 * Each VSIG is associated with a characteristic set; i.e. all VSIs under 2885 * a group have the same characteristic set. To check if there exists a VSIG 2886 * which has the same characteristics as the input characteristics; this 2887 * function will iterate through the XLT2 list and return the VSIG that has a 2888 * matching configuration. In order to make sure that priorities are accounted 2889 * for, the list must match exactly, including the order in which the 2890 * characteristics are listed. 2891 */ 2892 static enum ice_status 2893 ice_find_dup_props_vsig(struct ice_hw *hw, enum ice_block blk, 2894 struct LIST_HEAD_TYPE *chs, u16 *vsig) 2895 { 2896 struct ice_xlt2 *xlt2 = &hw->blk[blk].xlt2; 2897 u16 i; 2898 2899 for (i = 0; i < xlt2->count; i++) 2900 if (xlt2->vsig_tbl[i].in_use && 2901 ice_match_prop_lst(chs, &xlt2->vsig_tbl[i].prop_lst)) { 2902 *vsig = ICE_VSIG_VALUE(i, hw->pf_id); 2903 return ICE_SUCCESS; 2904 } 2905 2906 return ICE_ERR_DOES_NOT_EXIST; 2907 } 2908 2909 /** 2910 * ice_vsig_free - free VSI group 2911 * @hw: pointer to the hardware structure 2912 * @blk: HW block 2913 * @vsig: VSIG to remove 2914 * 2915 * The function will remove all VSIs associated with the input VSIG and move 2916 * them to the DEFAULT_VSIG and mark the VSIG available. 2917 */ 2918 static enum ice_status 2919 ice_vsig_free(struct ice_hw *hw, enum ice_block blk, u16 vsig) 2920 { 2921 struct ice_vsig_prof *dtmp, *del; 2922 struct ice_vsig_vsi *vsi_cur; 2923 u16 idx; 2924 2925 idx = vsig & ICE_VSIG_IDX_M; 2926 if (idx >= ICE_MAX_VSIGS) 2927 return ICE_ERR_PARAM; 2928 2929 if (!hw->blk[blk].xlt2.vsig_tbl[idx].in_use) 2930 return ICE_ERR_DOES_NOT_EXIST; 2931 2932 hw->blk[blk].xlt2.vsig_tbl[idx].in_use = false; 2933 2934 vsi_cur = hw->blk[blk].xlt2.vsig_tbl[idx].first_vsi; 2935 /* If the VSIG has at least 1 VSI then iterate through the 2936 * list and remove the VSIs before deleting the group. 2937 */ 2938 if (vsi_cur) { 2939 /* remove all vsis associated with this VSIG XLT2 entry */ 2940 do { 2941 struct ice_vsig_vsi *tmp = vsi_cur->next_vsi; 2942 2943 vsi_cur->vsig = ICE_DEFAULT_VSIG; 2944 vsi_cur->changed = 1; 2945 vsi_cur->next_vsi = NULL; 2946 vsi_cur = tmp; 2947 } while (vsi_cur); 2948 2949 /* NULL terminate head of VSI list */ 2950 hw->blk[blk].xlt2.vsig_tbl[idx].first_vsi = NULL; 2951 } 2952 2953 /* free characteristic list */ 2954 LIST_FOR_EACH_ENTRY_SAFE(del, dtmp, 2955 &hw->blk[blk].xlt2.vsig_tbl[idx].prop_lst, 2956 ice_vsig_prof, list) { 2957 LIST_DEL(&del->list); 2958 ice_free(hw, del); 2959 } 2960 2961 /* if VSIG characteristic list was cleared for reset 2962 * re-initialize the list head 2963 */ 2964 INIT_LIST_HEAD(&hw->blk[blk].xlt2.vsig_tbl[idx].prop_lst); 2965 2966 return ICE_SUCCESS; 2967 } 2968 2969 /** 2970 * ice_vsig_remove_vsi - remove VSI from VSIG 2971 * @hw: pointer to the hardware structure 2972 * @blk: HW block 2973 * @vsi: VSI to remove 2974 * @vsig: VSI group to remove from 2975 * 2976 * The function will remove the input VSI from its VSI group and move it 2977 * to the DEFAULT_VSIG. 2978 */ 2979 static enum ice_status 2980 ice_vsig_remove_vsi(struct ice_hw *hw, enum ice_block blk, u16 vsi, u16 vsig) 2981 { 2982 struct ice_vsig_vsi **vsi_head, *vsi_cur, *vsi_tgt; 2983 u16 idx; 2984 2985 idx = vsig & ICE_VSIG_IDX_M; 2986 2987 if (vsi >= ICE_MAX_VSI || idx >= ICE_MAX_VSIGS) 2988 return ICE_ERR_PARAM; 2989 2990 if (!hw->blk[blk].xlt2.vsig_tbl[idx].in_use) 2991 return ICE_ERR_DOES_NOT_EXIST; 2992 2993 /* entry already in default VSIG, don't have to remove */ 2994 if (idx == ICE_DEFAULT_VSIG) 2995 return ICE_SUCCESS; 2996 2997 vsi_head = &hw->blk[blk].xlt2.vsig_tbl[idx].first_vsi; 2998 if (!(*vsi_head)) 2999 return ICE_ERR_CFG; 3000 3001 vsi_tgt = &hw->blk[blk].xlt2.vsis[vsi]; 3002 vsi_cur = (*vsi_head); 3003 3004 /* iterate the VSI list, skip over the entry to be removed */ 3005 while (vsi_cur) { 3006 if (vsi_tgt == vsi_cur) { 3007 (*vsi_head) = vsi_cur->next_vsi; 3008 break; 3009 } 3010 vsi_head = &vsi_cur->next_vsi; 3011 vsi_cur = vsi_cur->next_vsi; 3012 } 3013 3014 /* verify if VSI was removed from group list */ 3015 if (!vsi_cur) 3016 return ICE_ERR_DOES_NOT_EXIST; 3017 3018 vsi_cur->vsig = ICE_DEFAULT_VSIG; 3019 vsi_cur->changed = 1; 3020 vsi_cur->next_vsi = NULL; 3021 3022 return ICE_SUCCESS; 3023 } 3024 3025 /** 3026 * ice_vsig_add_mv_vsi - add or move a VSI to a VSI group 3027 * @hw: pointer to the hardware structure 3028 * @blk: HW block 3029 * @vsi: VSI to move 3030 * @vsig: destination VSI group 3031 * 3032 * This function will move or add the input VSI to the target VSIG. 3033 * The function will find the original VSIG the VSI belongs to and 3034 * move the entry to the DEFAULT_VSIG, update the original VSIG and 3035 * then move entry to the new VSIG. 3036 */ 3037 static enum ice_status 3038 ice_vsig_add_mv_vsi(struct ice_hw *hw, enum ice_block blk, u16 vsi, u16 vsig) 3039 { 3040 struct ice_vsig_vsi *tmp; 3041 enum ice_status status; 3042 u16 orig_vsig, idx; 3043 3044 idx = vsig & ICE_VSIG_IDX_M; 3045 3046 if (vsi >= ICE_MAX_VSI || idx >= ICE_MAX_VSIGS) 3047 return ICE_ERR_PARAM; 3048 3049 /* if VSIG not in use and VSIG is not default type this VSIG 3050 * doesn't exist. 3051 */ 3052 if (!hw->blk[blk].xlt2.vsig_tbl[idx].in_use && 3053 vsig != ICE_DEFAULT_VSIG) 3054 return ICE_ERR_DOES_NOT_EXIST; 3055 3056 status = ice_vsig_find_vsi(hw, blk, vsi, &orig_vsig); 3057 if (status) 3058 return status; 3059 3060 /* no update required if vsigs match */ 3061 if (orig_vsig == vsig) 3062 return ICE_SUCCESS; 3063 3064 if (orig_vsig != ICE_DEFAULT_VSIG) { 3065 /* remove entry from orig_vsig and add to default VSIG */ 3066 status = ice_vsig_remove_vsi(hw, blk, vsi, orig_vsig); 3067 if (status) 3068 return status; 3069 } 3070 3071 if (idx == ICE_DEFAULT_VSIG) 3072 return ICE_SUCCESS; 3073 3074 /* Create VSI entry and add VSIG and prop_mask values */ 3075 hw->blk[blk].xlt2.vsis[vsi].vsig = vsig; 3076 hw->blk[blk].xlt2.vsis[vsi].changed = 1; 3077 3078 /* Add new entry to the head of the VSIG list */ 3079 tmp = hw->blk[blk].xlt2.vsig_tbl[idx].first_vsi; 3080 hw->blk[blk].xlt2.vsig_tbl[idx].first_vsi = 3081 &hw->blk[blk].xlt2.vsis[vsi]; 3082 hw->blk[blk].xlt2.vsis[vsi].next_vsi = tmp; 3083 hw->blk[blk].xlt2.t[vsi] = vsig; 3084 3085 return ICE_SUCCESS; 3086 } 3087 3088 /** 3089 * ice_prof_has_mask_idx - determine if profile index masking is identical 3090 * @hw: pointer to the hardware structure 3091 * @blk: HW block 3092 * @prof: profile to check 3093 * @idx: profile index to check 3094 * @mask: mask to match 3095 */ 3096 static bool 3097 ice_prof_has_mask_idx(struct ice_hw *hw, enum ice_block blk, u8 prof, u16 idx, 3098 u16 mask) 3099 { 3100 bool expect_no_mask = false; 3101 bool found = false; 3102 bool match = false; 3103 u16 i; 3104 3105 /* If mask is 0x0000 or 0xffff, then there is no masking */ 3106 if (mask == 0 || mask == 0xffff) 3107 expect_no_mask = true; 3108 3109 /* Scan the enabled masks on this profile, for the specified idx */ 3110 for (i = hw->blk[blk].masks.first; i < hw->blk[blk].masks.first + 3111 hw->blk[blk].masks.count; i++) 3112 if (hw->blk[blk].es.mask_ena[prof] & BIT(i)) 3113 if (hw->blk[blk].masks.masks[i].in_use && 3114 hw->blk[blk].masks.masks[i].idx == idx) { 3115 found = true; 3116 if (hw->blk[blk].masks.masks[i].mask == mask) 3117 match = true; 3118 break; 3119 } 3120 3121 if (expect_no_mask) { 3122 if (found) 3123 return false; 3124 } else { 3125 if (!match) 3126 return false; 3127 } 3128 3129 return true; 3130 } 3131 3132 /** 3133 * ice_prof_has_mask - determine if profile masking is identical 3134 * @hw: pointer to the hardware structure 3135 * @blk: HW block 3136 * @prof: profile to check 3137 * @masks: masks to match 3138 */ 3139 static bool 3140 ice_prof_has_mask(struct ice_hw *hw, enum ice_block blk, u8 prof, u16 *masks) 3141 { 3142 u16 i; 3143 3144 /* es->mask_ena[prof] will have the mask */ 3145 for (i = 0; i < hw->blk[blk].es.fvw; i++) 3146 if (!ice_prof_has_mask_idx(hw, blk, prof, i, masks[i])) 3147 return false; 3148 3149 return true; 3150 } 3151 3152 /** 3153 * ice_find_prof_id_with_mask - find profile ID for a given field vector 3154 * @hw: pointer to the hardware structure 3155 * @blk: HW block 3156 * @fv: field vector to search for 3157 * @masks: masks for fv 3158 * @prof_id: receives the profile ID 3159 */ 3160 static enum ice_status 3161 ice_find_prof_id_with_mask(struct ice_hw *hw, enum ice_block blk, 3162 struct ice_fv_word *fv, u16 *masks, u8 *prof_id) 3163 { 3164 struct ice_es *es = &hw->blk[blk].es; 3165 u8 i; 3166 3167 /* For FD and RSS, we don't want to re-use an existed profile with the 3168 * same field vector and mask. This will cause rule interference. 3169 */ 3170 if (blk == ICE_BLK_FD || blk == ICE_BLK_RSS) 3171 return ICE_ERR_DOES_NOT_EXIST; 3172 3173 for (i = 0; i < (u8)es->count; i++) { 3174 u16 off = i * es->fvw; 3175 3176 if (memcmp(&es->t[off], fv, es->fvw * sizeof(*fv))) 3177 continue; 3178 3179 /* check if masks settings are the same for this profile */ 3180 if (masks && !ice_prof_has_mask(hw, blk, i, masks)) 3181 continue; 3182 3183 *prof_id = i; 3184 return ICE_SUCCESS; 3185 } 3186 3187 return ICE_ERR_DOES_NOT_EXIST; 3188 } 3189 3190 /** 3191 * ice_prof_id_rsrc_type - get profile ID resource type for a block type 3192 * @blk: the block type 3193 * @rsrc_type: pointer to variable to receive the resource type 3194 */ 3195 static bool ice_prof_id_rsrc_type(enum ice_block blk, u16 *rsrc_type) 3196 { 3197 switch (blk) { 3198 case ICE_BLK_SW: 3199 *rsrc_type = ICE_AQC_RES_TYPE_SWITCH_PROF_BLDR_PROFID; 3200 break; 3201 case ICE_BLK_ACL: 3202 *rsrc_type = ICE_AQC_RES_TYPE_ACL_PROF_BLDR_PROFID; 3203 break; 3204 case ICE_BLK_FD: 3205 *rsrc_type = ICE_AQC_RES_TYPE_FD_PROF_BLDR_PROFID; 3206 break; 3207 case ICE_BLK_RSS: 3208 *rsrc_type = ICE_AQC_RES_TYPE_HASH_PROF_BLDR_PROFID; 3209 break; 3210 case ICE_BLK_PE: 3211 *rsrc_type = ICE_AQC_RES_TYPE_QHASH_PROF_BLDR_PROFID; 3212 break; 3213 default: 3214 return false; 3215 } 3216 return true; 3217 } 3218 3219 /** 3220 * ice_tcam_ent_rsrc_type - get TCAM entry resource type for a block type 3221 * @blk: the block type 3222 * @rsrc_type: pointer to variable to receive the resource type 3223 */ 3224 static bool ice_tcam_ent_rsrc_type(enum ice_block blk, u16 *rsrc_type) 3225 { 3226 switch (blk) { 3227 case ICE_BLK_SW: 3228 *rsrc_type = ICE_AQC_RES_TYPE_SWITCH_PROF_BLDR_TCAM; 3229 break; 3230 case ICE_BLK_ACL: 3231 *rsrc_type = ICE_AQC_RES_TYPE_ACL_PROF_BLDR_TCAM; 3232 break; 3233 case ICE_BLK_FD: 3234 *rsrc_type = ICE_AQC_RES_TYPE_FD_PROF_BLDR_TCAM; 3235 break; 3236 case ICE_BLK_RSS: 3237 *rsrc_type = ICE_AQC_RES_TYPE_HASH_PROF_BLDR_TCAM; 3238 break; 3239 case ICE_BLK_PE: 3240 *rsrc_type = ICE_AQC_RES_TYPE_QHASH_PROF_BLDR_TCAM; 3241 break; 3242 default: 3243 return false; 3244 } 3245 return true; 3246 } 3247 3248 /** 3249 * ice_alloc_tcam_ent - allocate hardware TCAM entry 3250 * @hw: pointer to the HW struct 3251 * @blk: the block to allocate the TCAM for 3252 * @btm: true to allocate from bottom of table, false to allocate from top 3253 * @tcam_idx: pointer to variable to receive the TCAM entry 3254 * 3255 * This function allocates a new entry in a Profile ID TCAM for a specific 3256 * block. 3257 */ 3258 static enum ice_status 3259 ice_alloc_tcam_ent(struct ice_hw *hw, enum ice_block blk, bool btm, 3260 u16 *tcam_idx) 3261 { 3262 u16 res_type; 3263 3264 if (!ice_tcam_ent_rsrc_type(blk, &res_type)) 3265 return ICE_ERR_PARAM; 3266 3267 return ice_alloc_hw_res(hw, res_type, 1, btm, tcam_idx); 3268 } 3269 3270 /** 3271 * ice_free_tcam_ent - free hardware TCAM entry 3272 * @hw: pointer to the HW struct 3273 * @blk: the block from which to free the TCAM entry 3274 * @tcam_idx: the TCAM entry to free 3275 * 3276 * This function frees an entry in a Profile ID TCAM for a specific block. 3277 */ 3278 static enum ice_status 3279 ice_free_tcam_ent(struct ice_hw *hw, enum ice_block blk, u16 tcam_idx) 3280 { 3281 u16 res_type; 3282 3283 if (!ice_tcam_ent_rsrc_type(blk, &res_type)) 3284 return ICE_ERR_PARAM; 3285 3286 return ice_free_hw_res(hw, res_type, 1, &tcam_idx); 3287 } 3288 3289 /** 3290 * ice_alloc_prof_id - allocate profile ID 3291 * @hw: pointer to the HW struct 3292 * @blk: the block to allocate the profile ID for 3293 * @prof_id: pointer to variable to receive the profile ID 3294 * 3295 * This function allocates a new profile ID, which also corresponds to a Field 3296 * Vector (Extraction Sequence) entry. 3297 */ 3298 static enum ice_status 3299 ice_alloc_prof_id(struct ice_hw *hw, enum ice_block blk, u8 *prof_id) 3300 { 3301 enum ice_status status; 3302 u16 res_type; 3303 u16 get_prof; 3304 3305 if (!ice_prof_id_rsrc_type(blk, &res_type)) 3306 return ICE_ERR_PARAM; 3307 3308 status = ice_alloc_hw_res(hw, res_type, 1, false, &get_prof); 3309 if (!status) 3310 *prof_id = (u8)get_prof; 3311 3312 return status; 3313 } 3314 3315 /** 3316 * ice_free_prof_id - free profile ID 3317 * @hw: pointer to the HW struct 3318 * @blk: the block from which to free the profile ID 3319 * @prof_id: the profile ID to free 3320 * 3321 * This function frees a profile ID, which also corresponds to a Field Vector. 3322 */ 3323 static enum ice_status 3324 ice_free_prof_id(struct ice_hw *hw, enum ice_block blk, u8 prof_id) 3325 { 3326 u16 tmp_prof_id = (u16)prof_id; 3327 u16 res_type; 3328 3329 if (!ice_prof_id_rsrc_type(blk, &res_type)) 3330 return ICE_ERR_PARAM; 3331 3332 return ice_free_hw_res(hw, res_type, 1, &tmp_prof_id); 3333 } 3334 3335 /** 3336 * ice_prof_inc_ref - increment reference count for profile 3337 * @hw: pointer to the HW struct 3338 * @blk: the block from which to free the profile ID 3339 * @prof_id: the profile ID for which to increment the reference count 3340 */ 3341 static enum ice_status 3342 ice_prof_inc_ref(struct ice_hw *hw, enum ice_block blk, u8 prof_id) 3343 { 3344 if (prof_id > hw->blk[blk].es.count) 3345 return ICE_ERR_PARAM; 3346 3347 hw->blk[blk].es.ref_count[prof_id]++; 3348 3349 return ICE_SUCCESS; 3350 } 3351 3352 /** 3353 * ice_write_prof_mask_reg - write profile mask register 3354 * @hw: pointer to the HW struct 3355 * @blk: hardware block 3356 * @mask_idx: mask index 3357 * @idx: index of the FV which will use the mask 3358 * @mask: the 16-bit mask 3359 */ 3360 static void 3361 ice_write_prof_mask_reg(struct ice_hw *hw, enum ice_block blk, u16 mask_idx, 3362 u16 idx, u16 mask) 3363 { 3364 u32 offset; 3365 u32 val; 3366 3367 switch (blk) { 3368 case ICE_BLK_RSS: 3369 offset = GLQF_HMASK(mask_idx); 3370 val = (idx << GLQF_HMASK_MSK_INDEX_S) & 3371 GLQF_HMASK_MSK_INDEX_M; 3372 val |= (mask << GLQF_HMASK_MASK_S) & GLQF_HMASK_MASK_M; 3373 break; 3374 case ICE_BLK_FD: 3375 offset = GLQF_FDMASK(mask_idx); 3376 val = (idx << GLQF_FDMASK_MSK_INDEX_S) & 3377 GLQF_FDMASK_MSK_INDEX_M; 3378 val |= (mask << GLQF_FDMASK_MASK_S) & 3379 GLQF_FDMASK_MASK_M; 3380 break; 3381 default: 3382 ice_debug(hw, ICE_DBG_PKG, "No profile masks for block %d\n", 3383 blk); 3384 return; 3385 } 3386 3387 wr32(hw, offset, val); 3388 ice_debug(hw, ICE_DBG_PKG, "write mask, blk %d (%d): %x = %x\n", 3389 blk, idx, offset, val); 3390 } 3391 3392 /** 3393 * ice_write_prof_mask_enable_res - write profile mask enable register 3394 * @hw: pointer to the HW struct 3395 * @blk: hardware block 3396 * @prof_id: profile ID 3397 * @enable_mask: enable mask 3398 */ 3399 static void 3400 ice_write_prof_mask_enable_res(struct ice_hw *hw, enum ice_block blk, 3401 u16 prof_id, u32 enable_mask) 3402 { 3403 u32 offset; 3404 3405 switch (blk) { 3406 case ICE_BLK_RSS: 3407 offset = GLQF_HMASK_SEL(prof_id); 3408 break; 3409 case ICE_BLK_FD: 3410 offset = GLQF_FDMASK_SEL(prof_id); 3411 break; 3412 default: 3413 ice_debug(hw, ICE_DBG_PKG, "No profile masks for block %d\n", 3414 blk); 3415 return; 3416 } 3417 3418 wr32(hw, offset, enable_mask); 3419 ice_debug(hw, ICE_DBG_PKG, "write mask enable, blk %d (%d): %x = %x\n", 3420 blk, prof_id, offset, enable_mask); 3421 } 3422 3423 /** 3424 * ice_init_prof_masks - initial prof masks 3425 * @hw: pointer to the HW struct 3426 * @blk: hardware block 3427 */ 3428 static void ice_init_prof_masks(struct ice_hw *hw, enum ice_block blk) 3429 { 3430 u16 per_pf; 3431 u16 i; 3432 3433 ice_init_lock(&hw->blk[blk].masks.lock); 3434 3435 per_pf = ICE_PROF_MASK_COUNT / hw->dev_caps.num_funcs; 3436 3437 hw->blk[blk].masks.count = per_pf; 3438 hw->blk[blk].masks.first = hw->pf_id * per_pf; 3439 3440 ice_memset(hw->blk[blk].masks.masks, 0, 3441 sizeof(hw->blk[blk].masks.masks), ICE_NONDMA_MEM); 3442 3443 for (i = hw->blk[blk].masks.first; 3444 i < hw->blk[blk].masks.first + hw->blk[blk].masks.count; i++) 3445 ice_write_prof_mask_reg(hw, blk, i, 0, 0); 3446 } 3447 3448 /** 3449 * ice_init_all_prof_masks - initial all prof masks 3450 * @hw: pointer to the HW struct 3451 */ 3452 void ice_init_all_prof_masks(struct ice_hw *hw) 3453 { 3454 ice_init_prof_masks(hw, ICE_BLK_RSS); 3455 ice_init_prof_masks(hw, ICE_BLK_FD); 3456 } 3457 3458 /** 3459 * ice_alloc_prof_mask - allocate profile mask 3460 * @hw: pointer to the HW struct 3461 * @blk: hardware block 3462 * @idx: index of FV which will use the mask 3463 * @mask: the 16-bit mask 3464 * @mask_idx: variable to receive the mask index 3465 */ 3466 static enum ice_status 3467 ice_alloc_prof_mask(struct ice_hw *hw, enum ice_block blk, u16 idx, u16 mask, 3468 u16 *mask_idx) 3469 { 3470 bool found_unused = false, found_copy = false; 3471 enum ice_status status = ICE_ERR_MAX_LIMIT; 3472 u16 unused_idx = 0, copy_idx = 0; 3473 u16 i; 3474 3475 if (blk != ICE_BLK_RSS && blk != ICE_BLK_FD) 3476 return ICE_ERR_PARAM; 3477 3478 ice_acquire_lock(&hw->blk[blk].masks.lock); 3479 3480 for (i = hw->blk[blk].masks.first; 3481 i < hw->blk[blk].masks.first + hw->blk[blk].masks.count; i++) 3482 if (hw->blk[blk].masks.masks[i].in_use) { 3483 /* if mask is in use and it exactly duplicates the 3484 * desired mask and index, then in can be reused 3485 */ 3486 if (hw->blk[blk].masks.masks[i].mask == mask && 3487 hw->blk[blk].masks.masks[i].idx == idx) { 3488 found_copy = true; 3489 copy_idx = i; 3490 break; 3491 } 3492 } else { 3493 /* save off unused index, but keep searching in case 3494 * there is an exact match later on 3495 */ 3496 if (!found_unused) { 3497 found_unused = true; 3498 unused_idx = i; 3499 } 3500 } 3501 3502 if (found_copy) 3503 i = copy_idx; 3504 else if (found_unused) 3505 i = unused_idx; 3506 else 3507 goto err_ice_alloc_prof_mask; 3508 3509 /* update mask for a new entry */ 3510 if (found_unused) { 3511 hw->blk[blk].masks.masks[i].in_use = true; 3512 hw->blk[blk].masks.masks[i].mask = mask; 3513 hw->blk[blk].masks.masks[i].idx = idx; 3514 hw->blk[blk].masks.masks[i].ref = 0; 3515 ice_write_prof_mask_reg(hw, blk, i, idx, mask); 3516 } 3517 3518 hw->blk[blk].masks.masks[i].ref++; 3519 *mask_idx = i; 3520 status = ICE_SUCCESS; 3521 3522 err_ice_alloc_prof_mask: 3523 ice_release_lock(&hw->blk[blk].masks.lock); 3524 3525 return status; 3526 } 3527 3528 /** 3529 * ice_free_prof_mask - free profile mask 3530 * @hw: pointer to the HW struct 3531 * @blk: hardware block 3532 * @mask_idx: index of mask 3533 */ 3534 static enum ice_status 3535 ice_free_prof_mask(struct ice_hw *hw, enum ice_block blk, u16 mask_idx) 3536 { 3537 if (blk != ICE_BLK_RSS && blk != ICE_BLK_FD) 3538 return ICE_ERR_PARAM; 3539 3540 if (!(mask_idx >= hw->blk[blk].masks.first && 3541 mask_idx < hw->blk[blk].masks.first + hw->blk[blk].masks.count)) 3542 return ICE_ERR_DOES_NOT_EXIST; 3543 3544 ice_acquire_lock(&hw->blk[blk].masks.lock); 3545 3546 if (!hw->blk[blk].masks.masks[mask_idx].in_use) 3547 goto exit_ice_free_prof_mask; 3548 3549 if (hw->blk[blk].masks.masks[mask_idx].ref > 1) { 3550 hw->blk[blk].masks.masks[mask_idx].ref--; 3551 goto exit_ice_free_prof_mask; 3552 } 3553 3554 /* remove mask */ 3555 hw->blk[blk].masks.masks[mask_idx].in_use = false; 3556 hw->blk[blk].masks.masks[mask_idx].mask = 0; 3557 hw->blk[blk].masks.masks[mask_idx].idx = 0; 3558 3559 /* update mask as unused entry */ 3560 ice_debug(hw, ICE_DBG_PKG, "Free mask, blk %d, mask %d\n", blk, 3561 mask_idx); 3562 ice_write_prof_mask_reg(hw, blk, mask_idx, 0, 0); 3563 3564 exit_ice_free_prof_mask: 3565 ice_release_lock(&hw->blk[blk].masks.lock); 3566 3567 return ICE_SUCCESS; 3568 } 3569 3570 /** 3571 * ice_free_prof_masks - free all profile masks for a profile 3572 * @hw: pointer to the HW struct 3573 * @blk: hardware block 3574 * @prof_id: profile ID 3575 */ 3576 static enum ice_status 3577 ice_free_prof_masks(struct ice_hw *hw, enum ice_block blk, u16 prof_id) 3578 { 3579 u32 mask_bm; 3580 u16 i; 3581 3582 if (blk != ICE_BLK_RSS && blk != ICE_BLK_FD) 3583 return ICE_ERR_PARAM; 3584 3585 mask_bm = hw->blk[blk].es.mask_ena[prof_id]; 3586 for (i = 0; i < BITS_PER_BYTE * sizeof(mask_bm); i++) 3587 if (mask_bm & BIT(i)) 3588 ice_free_prof_mask(hw, blk, i); 3589 3590 return ICE_SUCCESS; 3591 } 3592 3593 /** 3594 * ice_shutdown_prof_masks - releases lock for masking 3595 * @hw: pointer to the HW struct 3596 * @blk: hardware block 3597 * 3598 * This should be called before unloading the driver 3599 */ 3600 static void ice_shutdown_prof_masks(struct ice_hw *hw, enum ice_block blk) 3601 { 3602 u16 i; 3603 3604 ice_acquire_lock(&hw->blk[blk].masks.lock); 3605 3606 for (i = hw->blk[blk].masks.first; 3607 i < hw->blk[blk].masks.first + hw->blk[blk].masks.count; i++) { 3608 ice_write_prof_mask_reg(hw, blk, i, 0, 0); 3609 3610 hw->blk[blk].masks.masks[i].in_use = false; 3611 hw->blk[blk].masks.masks[i].idx = 0; 3612 hw->blk[blk].masks.masks[i].mask = 0; 3613 } 3614 3615 ice_release_lock(&hw->blk[blk].masks.lock); 3616 ice_destroy_lock(&hw->blk[blk].masks.lock); 3617 } 3618 3619 /** 3620 * ice_shutdown_all_prof_masks - releases all locks for masking 3621 * @hw: pointer to the HW struct 3622 * 3623 * This should be called before unloading the driver 3624 */ 3625 void ice_shutdown_all_prof_masks(struct ice_hw *hw) 3626 { 3627 ice_shutdown_prof_masks(hw, ICE_BLK_RSS); 3628 ice_shutdown_prof_masks(hw, ICE_BLK_FD); 3629 } 3630 3631 /** 3632 * ice_update_prof_masking - set registers according to masking 3633 * @hw: pointer to the HW struct 3634 * @blk: hardware block 3635 * @prof_id: profile ID 3636 * @masks: masks 3637 */ 3638 static enum ice_status 3639 ice_update_prof_masking(struct ice_hw *hw, enum ice_block blk, u16 prof_id, 3640 u16 *masks) 3641 { 3642 bool err = false; 3643 u32 ena_mask = 0; 3644 u16 idx; 3645 u16 i; 3646 3647 /* Only support FD and RSS masking, otherwise nothing to be done */ 3648 if (blk != ICE_BLK_RSS && blk != ICE_BLK_FD) 3649 return ICE_SUCCESS; 3650 3651 for (i = 0; i < hw->blk[blk].es.fvw; i++) 3652 if (masks[i] && masks[i] != 0xFFFF) { 3653 if (!ice_alloc_prof_mask(hw, blk, i, masks[i], &idx)) { 3654 ena_mask |= BIT(idx); 3655 } else { 3656 /* not enough bitmaps */ 3657 err = true; 3658 break; 3659 } 3660 } 3661 3662 if (err) { 3663 /* free any bitmaps we have allocated */ 3664 for (i = 0; i < BITS_PER_BYTE * sizeof(ena_mask); i++) 3665 if (ena_mask & BIT(i)) 3666 ice_free_prof_mask(hw, blk, i); 3667 3668 return ICE_ERR_OUT_OF_RANGE; 3669 } 3670 3671 /* enable the masks for this profile */ 3672 ice_write_prof_mask_enable_res(hw, blk, prof_id, ena_mask); 3673 3674 /* store enabled masks with profile so that they can be freed later */ 3675 hw->blk[blk].es.mask_ena[prof_id] = ena_mask; 3676 3677 return ICE_SUCCESS; 3678 } 3679 3680 /** 3681 * ice_write_es - write an extraction sequence to hardware 3682 * @hw: pointer to the HW struct 3683 * @blk: the block in which to write the extraction sequence 3684 * @prof_id: the profile ID to write 3685 * @fv: pointer to the extraction sequence to write - NULL to clear extraction 3686 */ 3687 static void 3688 ice_write_es(struct ice_hw *hw, enum ice_block blk, u8 prof_id, 3689 struct ice_fv_word *fv) 3690 { 3691 u16 off; 3692 3693 off = prof_id * hw->blk[blk].es.fvw; 3694 if (!fv) { 3695 ice_memset(&hw->blk[blk].es.t[off], 0, hw->blk[blk].es.fvw * 3696 sizeof(*fv), ICE_NONDMA_MEM); 3697 hw->blk[blk].es.written[prof_id] = false; 3698 } else { 3699 ice_memcpy(&hw->blk[blk].es.t[off], fv, hw->blk[blk].es.fvw * 3700 sizeof(*fv), ICE_NONDMA_TO_NONDMA); 3701 } 3702 } 3703 3704 /** 3705 * ice_prof_dec_ref - decrement reference count for profile 3706 * @hw: pointer to the HW struct 3707 * @blk: the block from which to free the profile ID 3708 * @prof_id: the profile ID for which to decrement the reference count 3709 */ 3710 static enum ice_status 3711 ice_prof_dec_ref(struct ice_hw *hw, enum ice_block blk, u8 prof_id) 3712 { 3713 if (prof_id > hw->blk[blk].es.count) 3714 return ICE_ERR_PARAM; 3715 3716 if (hw->blk[blk].es.ref_count[prof_id] > 0) { 3717 if (!--hw->blk[blk].es.ref_count[prof_id]) { 3718 ice_write_es(hw, blk, prof_id, NULL); 3719 ice_free_prof_masks(hw, blk, prof_id); 3720 return ice_free_prof_id(hw, blk, prof_id); 3721 } 3722 } 3723 3724 return ICE_SUCCESS; 3725 } 3726 3727 /* Block / table section IDs */ 3728 static const u32 ice_blk_sids[ICE_BLK_COUNT][ICE_SID_OFF_COUNT] = { 3729 /* SWITCH */ 3730 { ICE_SID_XLT1_SW, 3731 ICE_SID_XLT2_SW, 3732 ICE_SID_PROFID_TCAM_SW, 3733 ICE_SID_PROFID_REDIR_SW, 3734 ICE_SID_FLD_VEC_SW 3735 }, 3736 3737 /* ACL */ 3738 { ICE_SID_XLT1_ACL, 3739 ICE_SID_XLT2_ACL, 3740 ICE_SID_PROFID_TCAM_ACL, 3741 ICE_SID_PROFID_REDIR_ACL, 3742 ICE_SID_FLD_VEC_ACL 3743 }, 3744 3745 /* FD */ 3746 { ICE_SID_XLT1_FD, 3747 ICE_SID_XLT2_FD, 3748 ICE_SID_PROFID_TCAM_FD, 3749 ICE_SID_PROFID_REDIR_FD, 3750 ICE_SID_FLD_VEC_FD 3751 }, 3752 3753 /* RSS */ 3754 { ICE_SID_XLT1_RSS, 3755 ICE_SID_XLT2_RSS, 3756 ICE_SID_PROFID_TCAM_RSS, 3757 ICE_SID_PROFID_REDIR_RSS, 3758 ICE_SID_FLD_VEC_RSS 3759 }, 3760 3761 /* PE */ 3762 { ICE_SID_XLT1_PE, 3763 ICE_SID_XLT2_PE, 3764 ICE_SID_PROFID_TCAM_PE, 3765 ICE_SID_PROFID_REDIR_PE, 3766 ICE_SID_FLD_VEC_PE 3767 } 3768 }; 3769 3770 /** 3771 * ice_init_sw_xlt1_db - init software XLT1 database from HW tables 3772 * @hw: pointer to the hardware structure 3773 * @blk: the HW block to initialize 3774 */ 3775 static void ice_init_sw_xlt1_db(struct ice_hw *hw, enum ice_block blk) 3776 { 3777 u16 pt; 3778 3779 for (pt = 0; pt < hw->blk[blk].xlt1.count; pt++) { 3780 u8 ptg; 3781 3782 ptg = hw->blk[blk].xlt1.t[pt]; 3783 if (ptg != ICE_DEFAULT_PTG) { 3784 ice_ptg_alloc_val(hw, blk, ptg); 3785 ice_ptg_add_mv_ptype(hw, blk, pt, ptg); 3786 } 3787 } 3788 } 3789 3790 /** 3791 * ice_init_sw_xlt2_db - init software XLT2 database from HW tables 3792 * @hw: pointer to the hardware structure 3793 * @blk: the HW block to initialize 3794 */ 3795 static void ice_init_sw_xlt2_db(struct ice_hw *hw, enum ice_block blk) 3796 { 3797 u16 vsi; 3798 3799 for (vsi = 0; vsi < hw->blk[blk].xlt2.count; vsi++) { 3800 u16 vsig; 3801 3802 vsig = hw->blk[blk].xlt2.t[vsi]; 3803 if (vsig) { 3804 ice_vsig_alloc_val(hw, blk, vsig); 3805 ice_vsig_add_mv_vsi(hw, blk, vsi, vsig); 3806 /* no changes at this time, since this has been 3807 * initialized from the original package 3808 */ 3809 hw->blk[blk].xlt2.vsis[vsi].changed = 0; 3810 } 3811 } 3812 } 3813 3814 /** 3815 * ice_init_sw_db - init software database from HW tables 3816 * @hw: pointer to the hardware structure 3817 */ 3818 static void ice_init_sw_db(struct ice_hw *hw) 3819 { 3820 u16 i; 3821 3822 for (i = 0; i < ICE_BLK_COUNT; i++) { 3823 ice_init_sw_xlt1_db(hw, (enum ice_block)i); 3824 ice_init_sw_xlt2_db(hw, (enum ice_block)i); 3825 } 3826 } 3827 3828 /** 3829 * ice_fill_tbl - Reads content of a single table type into database 3830 * @hw: pointer to the hardware structure 3831 * @block_id: Block ID of the table to copy 3832 * @sid: Section ID of the table to copy 3833 * 3834 * Will attempt to read the entire content of a given table of a single block 3835 * into the driver database. We assume that the buffer will always 3836 * be as large or larger than the data contained in the package. If 3837 * this condition is not met, there is most likely an error in the package 3838 * contents. 3839 */ 3840 static void ice_fill_tbl(struct ice_hw *hw, enum ice_block block_id, u32 sid) 3841 { 3842 u32 dst_len, sect_len, offset = 0; 3843 struct ice_prof_redir_section *pr; 3844 struct ice_prof_id_section *pid; 3845 struct ice_xlt1_section *xlt1; 3846 struct ice_xlt2_section *xlt2; 3847 struct ice_sw_fv_section *es; 3848 struct ice_pkg_enum state; 3849 u8 *src, *dst; 3850 void *sect; 3851 3852 /* if the HW segment pointer is null then the first iteration of 3853 * ice_pkg_enum_section() will fail. In this case the HW tables will 3854 * not be filled and return success. 3855 */ 3856 if (!hw->seg) { 3857 ice_debug(hw, ICE_DBG_PKG, "hw->seg is NULL, tables are not filled\n"); 3858 return; 3859 } 3860 3861 ice_memset(&state, 0, sizeof(state), ICE_NONDMA_MEM); 3862 3863 sect = ice_pkg_enum_section(hw->seg, &state, sid); 3864 3865 while (sect) { 3866 switch (sid) { 3867 case ICE_SID_XLT1_SW: 3868 case ICE_SID_XLT1_FD: 3869 case ICE_SID_XLT1_RSS: 3870 case ICE_SID_XLT1_ACL: 3871 case ICE_SID_XLT1_PE: 3872 xlt1 = (struct ice_xlt1_section *)sect; 3873 src = xlt1->value; 3874 sect_len = LE16_TO_CPU(xlt1->count) * 3875 sizeof(*hw->blk[block_id].xlt1.t); 3876 dst = hw->blk[block_id].xlt1.t; 3877 dst_len = hw->blk[block_id].xlt1.count * 3878 sizeof(*hw->blk[block_id].xlt1.t); 3879 break; 3880 case ICE_SID_XLT2_SW: 3881 case ICE_SID_XLT2_FD: 3882 case ICE_SID_XLT2_RSS: 3883 case ICE_SID_XLT2_ACL: 3884 case ICE_SID_XLT2_PE: 3885 xlt2 = (struct ice_xlt2_section *)sect; 3886 src = (_FORCE_ u8 *)xlt2->value; 3887 sect_len = LE16_TO_CPU(xlt2->count) * 3888 sizeof(*hw->blk[block_id].xlt2.t); 3889 dst = (u8 *)hw->blk[block_id].xlt2.t; 3890 dst_len = hw->blk[block_id].xlt2.count * 3891 sizeof(*hw->blk[block_id].xlt2.t); 3892 break; 3893 case ICE_SID_PROFID_TCAM_SW: 3894 case ICE_SID_PROFID_TCAM_FD: 3895 case ICE_SID_PROFID_TCAM_RSS: 3896 case ICE_SID_PROFID_TCAM_ACL: 3897 case ICE_SID_PROFID_TCAM_PE: 3898 pid = (struct ice_prof_id_section *)sect; 3899 src = (u8 *)pid->entry; 3900 sect_len = LE16_TO_CPU(pid->count) * 3901 sizeof(*hw->blk[block_id].prof.t); 3902 dst = (u8 *)hw->blk[block_id].prof.t; 3903 dst_len = hw->blk[block_id].prof.count * 3904 sizeof(*hw->blk[block_id].prof.t); 3905 break; 3906 case ICE_SID_PROFID_REDIR_SW: 3907 case ICE_SID_PROFID_REDIR_FD: 3908 case ICE_SID_PROFID_REDIR_RSS: 3909 case ICE_SID_PROFID_REDIR_ACL: 3910 case ICE_SID_PROFID_REDIR_PE: 3911 pr = (struct ice_prof_redir_section *)sect; 3912 src = pr->redir_value; 3913 sect_len = LE16_TO_CPU(pr->count) * 3914 sizeof(*hw->blk[block_id].prof_redir.t); 3915 dst = hw->blk[block_id].prof_redir.t; 3916 dst_len = hw->blk[block_id].prof_redir.count * 3917 sizeof(*hw->blk[block_id].prof_redir.t); 3918 break; 3919 case ICE_SID_FLD_VEC_SW: 3920 case ICE_SID_FLD_VEC_FD: 3921 case ICE_SID_FLD_VEC_RSS: 3922 case ICE_SID_FLD_VEC_ACL: 3923 case ICE_SID_FLD_VEC_PE: 3924 es = (struct ice_sw_fv_section *)sect; 3925 src = (u8 *)es->fv; 3926 sect_len = (u32)(LE16_TO_CPU(es->count) * 3927 hw->blk[block_id].es.fvw) * 3928 sizeof(*hw->blk[block_id].es.t); 3929 dst = (u8 *)hw->blk[block_id].es.t; 3930 dst_len = (u32)(hw->blk[block_id].es.count * 3931 hw->blk[block_id].es.fvw) * 3932 sizeof(*hw->blk[block_id].es.t); 3933 break; 3934 default: 3935 return; 3936 } 3937 3938 /* if the section offset exceeds destination length, terminate 3939 * table fill. 3940 */ 3941 if (offset > dst_len) 3942 return; 3943 3944 /* if the sum of section size and offset exceed destination size 3945 * then we are out of bounds of the HW table size for that PF. 3946 * Changing section length to fill the remaining table space 3947 * of that PF. 3948 */ 3949 if ((offset + sect_len) > dst_len) 3950 sect_len = dst_len - offset; 3951 3952 ice_memcpy(dst + offset, src, sect_len, ICE_NONDMA_TO_NONDMA); 3953 offset += sect_len; 3954 sect = ice_pkg_enum_section(NULL, &state, sid); 3955 } 3956 } 3957 3958 /** 3959 * ice_fill_blk_tbls - Read package context for tables 3960 * @hw: pointer to the hardware structure 3961 * 3962 * Reads the current package contents and populates the driver 3963 * database with the data iteratively for all advanced feature 3964 * blocks. Assume that the HW tables have been allocated. 3965 */ 3966 void ice_fill_blk_tbls(struct ice_hw *hw) 3967 { 3968 u8 i; 3969 3970 for (i = 0; i < ICE_BLK_COUNT; i++) { 3971 enum ice_block blk_id = (enum ice_block)i; 3972 3973 ice_fill_tbl(hw, blk_id, hw->blk[blk_id].xlt1.sid); 3974 ice_fill_tbl(hw, blk_id, hw->blk[blk_id].xlt2.sid); 3975 ice_fill_tbl(hw, blk_id, hw->blk[blk_id].prof.sid); 3976 ice_fill_tbl(hw, blk_id, hw->blk[blk_id].prof_redir.sid); 3977 ice_fill_tbl(hw, blk_id, hw->blk[blk_id].es.sid); 3978 } 3979 3980 ice_init_sw_db(hw); 3981 } 3982 3983 /** 3984 * ice_free_prof_map - free profile map 3985 * @hw: pointer to the hardware structure 3986 * @blk_idx: HW block index 3987 */ 3988 static void ice_free_prof_map(struct ice_hw *hw, u8 blk_idx) 3989 { 3990 struct ice_es *es = &hw->blk[blk_idx].es; 3991 struct ice_prof_map *del, *tmp; 3992 3993 ice_acquire_lock(&es->prof_map_lock); 3994 LIST_FOR_EACH_ENTRY_SAFE(del, tmp, &es->prof_map, 3995 ice_prof_map, list) { 3996 LIST_DEL(&del->list); 3997 ice_free(hw, del); 3998 } 3999 INIT_LIST_HEAD(&es->prof_map); 4000 ice_release_lock(&es->prof_map_lock); 4001 } 4002 4003 /** 4004 * ice_free_flow_profs - free flow profile entries 4005 * @hw: pointer to the hardware structure 4006 * @blk_idx: HW block index 4007 */ 4008 static void ice_free_flow_profs(struct ice_hw *hw, u8 blk_idx) 4009 { 4010 struct ice_flow_prof *p, *tmp; 4011 4012 ice_acquire_lock(&hw->fl_profs_locks[blk_idx]); 4013 LIST_FOR_EACH_ENTRY_SAFE(p, tmp, &hw->fl_profs[blk_idx], 4014 ice_flow_prof, l_entry) { 4015 struct ice_flow_entry *e, *t; 4016 4017 LIST_FOR_EACH_ENTRY_SAFE(e, t, &p->entries, 4018 ice_flow_entry, l_entry) 4019 ice_flow_rem_entry(hw, (enum ice_block)blk_idx, 4020 ICE_FLOW_ENTRY_HNDL(e)); 4021 4022 LIST_DEL(&p->l_entry); 4023 if (p->acts) 4024 ice_free(hw, p->acts); 4025 4026 ice_destroy_lock(&p->entries_lock); 4027 ice_free(hw, p); 4028 } 4029 ice_release_lock(&hw->fl_profs_locks[blk_idx]); 4030 4031 /* if driver is in reset and tables are being cleared 4032 * re-initialize the flow profile list heads 4033 */ 4034 INIT_LIST_HEAD(&hw->fl_profs[blk_idx]); 4035 } 4036 4037 /** 4038 * ice_free_vsig_tbl - free complete VSIG table entries 4039 * @hw: pointer to the hardware structure 4040 * @blk: the HW block on which to free the VSIG table entries 4041 */ 4042 static void ice_free_vsig_tbl(struct ice_hw *hw, enum ice_block blk) 4043 { 4044 u16 i; 4045 4046 if (!hw->blk[blk].xlt2.vsig_tbl) 4047 return; 4048 4049 for (i = 1; i < ICE_MAX_VSIGS; i++) 4050 if (hw->blk[blk].xlt2.vsig_tbl[i].in_use) 4051 ice_vsig_free(hw, blk, i); 4052 } 4053 4054 /** 4055 * ice_free_hw_tbls - free hardware table memory 4056 * @hw: pointer to the hardware structure 4057 */ 4058 void ice_free_hw_tbls(struct ice_hw *hw) 4059 { 4060 struct ice_rss_cfg *r, *rt; 4061 u8 i; 4062 4063 for (i = 0; i < ICE_BLK_COUNT; i++) { 4064 if (hw->blk[i].is_list_init) { 4065 struct ice_es *es = &hw->blk[i].es; 4066 4067 ice_free_prof_map(hw, i); 4068 ice_destroy_lock(&es->prof_map_lock); 4069 ice_free_flow_profs(hw, i); 4070 ice_destroy_lock(&hw->fl_profs_locks[i]); 4071 4072 hw->blk[i].is_list_init = false; 4073 } 4074 ice_free_vsig_tbl(hw, (enum ice_block)i); 4075 ice_free(hw, hw->blk[i].xlt1.ptypes); 4076 ice_free(hw, hw->blk[i].xlt1.ptg_tbl); 4077 ice_free(hw, hw->blk[i].xlt1.t); 4078 ice_free(hw, hw->blk[i].xlt2.t); 4079 ice_free(hw, hw->blk[i].xlt2.vsig_tbl); 4080 ice_free(hw, hw->blk[i].xlt2.vsis); 4081 ice_free(hw, hw->blk[i].prof.t); 4082 ice_free(hw, hw->blk[i].prof_redir.t); 4083 ice_free(hw, hw->blk[i].es.t); 4084 ice_free(hw, hw->blk[i].es.ref_count); 4085 ice_free(hw, hw->blk[i].es.written); 4086 ice_free(hw, hw->blk[i].es.mask_ena); 4087 } 4088 4089 LIST_FOR_EACH_ENTRY_SAFE(r, rt, &hw->rss_list_head, 4090 ice_rss_cfg, l_entry) { 4091 LIST_DEL(&r->l_entry); 4092 ice_free(hw, r); 4093 } 4094 ice_destroy_lock(&hw->rss_locks); 4095 if (!hw->dcf_enabled) 4096 ice_shutdown_all_prof_masks(hw); 4097 ice_memset(hw->blk, 0, sizeof(hw->blk), ICE_NONDMA_MEM); 4098 } 4099 4100 /** 4101 * ice_init_flow_profs - init flow profile locks and list heads 4102 * @hw: pointer to the hardware structure 4103 * @blk_idx: HW block index 4104 */ 4105 static void ice_init_flow_profs(struct ice_hw *hw, u8 blk_idx) 4106 { 4107 ice_init_lock(&hw->fl_profs_locks[blk_idx]); 4108 INIT_LIST_HEAD(&hw->fl_profs[blk_idx]); 4109 } 4110 4111 /** 4112 * ice_clear_hw_tbls - clear HW tables and flow profiles 4113 * @hw: pointer to the hardware structure 4114 */ 4115 void ice_clear_hw_tbls(struct ice_hw *hw) 4116 { 4117 u8 i; 4118 4119 for (i = 0; i < ICE_BLK_COUNT; i++) { 4120 struct ice_prof_redir *prof_redir = &hw->blk[i].prof_redir; 4121 struct ice_prof_tcam *prof = &hw->blk[i].prof; 4122 struct ice_xlt1 *xlt1 = &hw->blk[i].xlt1; 4123 struct ice_xlt2 *xlt2 = &hw->blk[i].xlt2; 4124 struct ice_es *es = &hw->blk[i].es; 4125 4126 if (hw->blk[i].is_list_init) { 4127 ice_free_prof_map(hw, i); 4128 ice_free_flow_profs(hw, i); 4129 } 4130 4131 ice_free_vsig_tbl(hw, (enum ice_block)i); 4132 4133 ice_memset(xlt1->ptypes, 0, xlt1->count * sizeof(*xlt1->ptypes), 4134 ICE_NONDMA_MEM); 4135 ice_memset(xlt1->ptg_tbl, 0, 4136 ICE_MAX_PTGS * sizeof(*xlt1->ptg_tbl), 4137 ICE_NONDMA_MEM); 4138 ice_memset(xlt1->t, 0, xlt1->count * sizeof(*xlt1->t), 4139 ICE_NONDMA_MEM); 4140 4141 ice_memset(xlt2->vsis, 0, xlt2->count * sizeof(*xlt2->vsis), 4142 ICE_NONDMA_MEM); 4143 ice_memset(xlt2->vsig_tbl, 0, 4144 xlt2->count * sizeof(*xlt2->vsig_tbl), 4145 ICE_NONDMA_MEM); 4146 ice_memset(xlt2->t, 0, xlt2->count * sizeof(*xlt2->t), 4147 ICE_NONDMA_MEM); 4148 4149 ice_memset(prof->t, 0, prof->count * sizeof(*prof->t), 4150 ICE_NONDMA_MEM); 4151 ice_memset(prof_redir->t, 0, 4152 prof_redir->count * sizeof(*prof_redir->t), 4153 ICE_NONDMA_MEM); 4154 4155 ice_memset(es->t, 0, es->count * sizeof(*es->t) * es->fvw, 4156 ICE_NONDMA_MEM); 4157 ice_memset(es->ref_count, 0, es->count * sizeof(*es->ref_count), 4158 ICE_NONDMA_MEM); 4159 ice_memset(es->written, 0, es->count * sizeof(*es->written), 4160 ICE_NONDMA_MEM); 4161 ice_memset(es->mask_ena, 0, es->count * sizeof(*es->mask_ena), 4162 ICE_NONDMA_MEM); 4163 } 4164 } 4165 4166 /** 4167 * ice_init_hw_tbls - init hardware table memory 4168 * @hw: pointer to the hardware structure 4169 */ 4170 enum ice_status ice_init_hw_tbls(struct ice_hw *hw) 4171 { 4172 u8 i; 4173 4174 ice_init_lock(&hw->rss_locks); 4175 INIT_LIST_HEAD(&hw->rss_list_head); 4176 if (!hw->dcf_enabled) 4177 ice_init_all_prof_masks(hw); 4178 for (i = 0; i < ICE_BLK_COUNT; i++) { 4179 struct ice_prof_redir *prof_redir = &hw->blk[i].prof_redir; 4180 struct ice_prof_tcam *prof = &hw->blk[i].prof; 4181 struct ice_xlt1 *xlt1 = &hw->blk[i].xlt1; 4182 struct ice_xlt2 *xlt2 = &hw->blk[i].xlt2; 4183 struct ice_es *es = &hw->blk[i].es; 4184 u16 j; 4185 4186 if (hw->blk[i].is_list_init) 4187 continue; 4188 4189 ice_init_flow_profs(hw, i); 4190 ice_init_lock(&es->prof_map_lock); 4191 INIT_LIST_HEAD(&es->prof_map); 4192 hw->blk[i].is_list_init = true; 4193 4194 hw->blk[i].overwrite = blk_sizes[i].overwrite; 4195 es->reverse = blk_sizes[i].reverse; 4196 4197 xlt1->sid = ice_blk_sids[i][ICE_SID_XLT1_OFF]; 4198 xlt1->count = blk_sizes[i].xlt1; 4199 4200 xlt1->ptypes = (struct ice_ptg_ptype *) 4201 ice_calloc(hw, xlt1->count, sizeof(*xlt1->ptypes)); 4202 4203 if (!xlt1->ptypes) 4204 goto err; 4205 4206 xlt1->ptg_tbl = (struct ice_ptg_entry *) 4207 ice_calloc(hw, ICE_MAX_PTGS, sizeof(*xlt1->ptg_tbl)); 4208 4209 if (!xlt1->ptg_tbl) 4210 goto err; 4211 4212 xlt1->t = (u8 *)ice_calloc(hw, xlt1->count, sizeof(*xlt1->t)); 4213 if (!xlt1->t) 4214 goto err; 4215 4216 xlt2->sid = ice_blk_sids[i][ICE_SID_XLT2_OFF]; 4217 xlt2->count = blk_sizes[i].xlt2; 4218 4219 xlt2->vsis = (struct ice_vsig_vsi *) 4220 ice_calloc(hw, xlt2->count, sizeof(*xlt2->vsis)); 4221 4222 if (!xlt2->vsis) 4223 goto err; 4224 4225 xlt2->vsig_tbl = (struct ice_vsig_entry *) 4226 ice_calloc(hw, xlt2->count, sizeof(*xlt2->vsig_tbl)); 4227 if (!xlt2->vsig_tbl) 4228 goto err; 4229 4230 for (j = 0; j < xlt2->count; j++) 4231 INIT_LIST_HEAD(&xlt2->vsig_tbl[j].prop_lst); 4232 4233 xlt2->t = (u16 *)ice_calloc(hw, xlt2->count, sizeof(*xlt2->t)); 4234 if (!xlt2->t) 4235 goto err; 4236 4237 prof->sid = ice_blk_sids[i][ICE_SID_PR_OFF]; 4238 prof->count = blk_sizes[i].prof_tcam; 4239 prof->max_prof_id = blk_sizes[i].prof_id; 4240 prof->cdid_bits = blk_sizes[i].prof_cdid_bits; 4241 prof->t = (struct ice_prof_tcam_entry *) 4242 ice_calloc(hw, prof->count, sizeof(*prof->t)); 4243 4244 if (!prof->t) 4245 goto err; 4246 4247 prof_redir->sid = ice_blk_sids[i][ICE_SID_PR_REDIR_OFF]; 4248 prof_redir->count = blk_sizes[i].prof_redir; 4249 prof_redir->t = (u8 *)ice_calloc(hw, prof_redir->count, 4250 sizeof(*prof_redir->t)); 4251 4252 if (!prof_redir->t) 4253 goto err; 4254 4255 es->sid = ice_blk_sids[i][ICE_SID_ES_OFF]; 4256 es->count = blk_sizes[i].es; 4257 es->fvw = blk_sizes[i].fvw; 4258 es->t = (struct ice_fv_word *) 4259 ice_calloc(hw, (u32)(es->count * es->fvw), 4260 sizeof(*es->t)); 4261 if (!es->t) 4262 goto err; 4263 4264 es->ref_count = (u16 *) 4265 ice_calloc(hw, es->count, sizeof(*es->ref_count)); 4266 4267 if (!es->ref_count) 4268 goto err; 4269 4270 es->written = (u8 *) 4271 ice_calloc(hw, es->count, sizeof(*es->written)); 4272 4273 if (!es->written) 4274 goto err; 4275 4276 es->mask_ena = (u32 *) 4277 ice_calloc(hw, es->count, sizeof(*es->mask_ena)); 4278 4279 if (!es->mask_ena) 4280 goto err; 4281 } 4282 return ICE_SUCCESS; 4283 4284 err: 4285 ice_free_hw_tbls(hw); 4286 return ICE_ERR_NO_MEMORY; 4287 } 4288 4289 /** 4290 * ice_prof_gen_key - generate profile ID key 4291 * @hw: pointer to the HW struct 4292 * @blk: the block in which to write profile ID to 4293 * @ptg: packet type group (PTG) portion of key 4294 * @vsig: VSIG portion of key 4295 * @cdid: CDID portion of key 4296 * @flags: flag portion of key 4297 * @vl_msk: valid mask 4298 * @dc_msk: don't care mask 4299 * @nm_msk: never match mask 4300 * @key: output of profile ID key 4301 */ 4302 static enum ice_status 4303 ice_prof_gen_key(struct ice_hw *hw, enum ice_block blk, u8 ptg, u16 vsig, 4304 u8 cdid, u16 flags, u8 vl_msk[ICE_TCAM_KEY_VAL_SZ], 4305 u8 dc_msk[ICE_TCAM_KEY_VAL_SZ], u8 nm_msk[ICE_TCAM_KEY_VAL_SZ], 4306 u8 key[ICE_TCAM_KEY_SZ]) 4307 { 4308 struct ice_prof_id_key inkey; 4309 4310 inkey.xlt1 = ptg; 4311 inkey.xlt2_cdid = CPU_TO_LE16(vsig); 4312 inkey.flags = CPU_TO_LE16(flags); 4313 4314 switch (hw->blk[blk].prof.cdid_bits) { 4315 case 0: 4316 break; 4317 case 2: 4318 #define ICE_CD_2_M 0xC000U 4319 #define ICE_CD_2_S 14 4320 inkey.xlt2_cdid &= ~CPU_TO_LE16(ICE_CD_2_M); 4321 inkey.xlt2_cdid |= CPU_TO_LE16(BIT(cdid) << ICE_CD_2_S); 4322 break; 4323 case 4: 4324 #define ICE_CD_4_M 0xF000U 4325 #define ICE_CD_4_S 12 4326 inkey.xlt2_cdid &= ~CPU_TO_LE16(ICE_CD_4_M); 4327 inkey.xlt2_cdid |= CPU_TO_LE16(BIT(cdid) << ICE_CD_4_S); 4328 break; 4329 case 8: 4330 #define ICE_CD_8_M 0xFF00U 4331 #define ICE_CD_8_S 16 4332 inkey.xlt2_cdid &= ~CPU_TO_LE16(ICE_CD_8_M); 4333 inkey.xlt2_cdid |= CPU_TO_LE16(BIT(cdid) << ICE_CD_8_S); 4334 break; 4335 default: 4336 ice_debug(hw, ICE_DBG_PKG, "Error in profile config\n"); 4337 break; 4338 } 4339 4340 return ice_set_key(key, ICE_TCAM_KEY_SZ, (u8 *)&inkey, vl_msk, dc_msk, 4341 nm_msk, 0, ICE_TCAM_KEY_SZ / 2); 4342 } 4343 4344 /** 4345 * ice_tcam_write_entry - write TCAM entry 4346 * @hw: pointer to the HW struct 4347 * @blk: the block in which to write profile ID to 4348 * @idx: the entry index to write to 4349 * @prof_id: profile ID 4350 * @ptg: packet type group (PTG) portion of key 4351 * @vsig: VSIG portion of key 4352 * @cdid: CDID portion of key 4353 * @flags: flag portion of key 4354 * @vl_msk: valid mask 4355 * @dc_msk: don't care mask 4356 * @nm_msk: never match mask 4357 */ 4358 static enum ice_status 4359 ice_tcam_write_entry(struct ice_hw *hw, enum ice_block blk, u16 idx, 4360 u8 prof_id, u8 ptg, u16 vsig, u8 cdid, u16 flags, 4361 u8 vl_msk[ICE_TCAM_KEY_VAL_SZ], 4362 u8 dc_msk[ICE_TCAM_KEY_VAL_SZ], 4363 u8 nm_msk[ICE_TCAM_KEY_VAL_SZ]) 4364 { 4365 struct ice_prof_tcam_entry; 4366 enum ice_status status; 4367 4368 status = ice_prof_gen_key(hw, blk, ptg, vsig, cdid, flags, vl_msk, 4369 dc_msk, nm_msk, hw->blk[blk].prof.t[idx].key); 4370 if (!status) { 4371 hw->blk[blk].prof.t[idx].addr = CPU_TO_LE16(idx); 4372 hw->blk[blk].prof.t[idx].prof_id = prof_id; 4373 } 4374 4375 return status; 4376 } 4377 4378 /** 4379 * ice_vsig_get_ref - returns number of VSIs belong to a VSIG 4380 * @hw: pointer to the hardware structure 4381 * @blk: HW block 4382 * @vsig: VSIG to query 4383 * @refs: pointer to variable to receive the reference count 4384 */ 4385 static enum ice_status 4386 ice_vsig_get_ref(struct ice_hw *hw, enum ice_block blk, u16 vsig, u16 *refs) 4387 { 4388 u16 idx = vsig & ICE_VSIG_IDX_M; 4389 struct ice_vsig_vsi *ptr; 4390 4391 *refs = 0; 4392 4393 if (!hw->blk[blk].xlt2.vsig_tbl[idx].in_use) 4394 return ICE_ERR_DOES_NOT_EXIST; 4395 4396 ptr = hw->blk[blk].xlt2.vsig_tbl[idx].first_vsi; 4397 while (ptr) { 4398 (*refs)++; 4399 ptr = ptr->next_vsi; 4400 } 4401 4402 return ICE_SUCCESS; 4403 } 4404 4405 /** 4406 * ice_has_prof_vsig - check to see if VSIG has a specific profile 4407 * @hw: pointer to the hardware structure 4408 * @blk: HW block 4409 * @vsig: VSIG to check against 4410 * @hdl: profile handle 4411 */ 4412 static bool 4413 ice_has_prof_vsig(struct ice_hw *hw, enum ice_block blk, u16 vsig, u64 hdl) 4414 { 4415 u16 idx = vsig & ICE_VSIG_IDX_M; 4416 struct ice_vsig_prof *ent; 4417 4418 LIST_FOR_EACH_ENTRY(ent, &hw->blk[blk].xlt2.vsig_tbl[idx].prop_lst, 4419 ice_vsig_prof, list) 4420 if (ent->profile_cookie == hdl) 4421 return true; 4422 4423 ice_debug(hw, ICE_DBG_INIT, "Characteristic list for VSI group %d not found.\n", 4424 vsig); 4425 return false; 4426 } 4427 4428 /** 4429 * ice_prof_bld_es - build profile ID extraction sequence changes 4430 * @hw: pointer to the HW struct 4431 * @blk: hardware block 4432 * @bld: the update package buffer build to add to 4433 * @chgs: the list of changes to make in hardware 4434 */ 4435 static enum ice_status 4436 ice_prof_bld_es(struct ice_hw *hw, enum ice_block blk, 4437 struct ice_buf_build *bld, struct LIST_HEAD_TYPE *chgs) 4438 { 4439 u16 vec_size = hw->blk[blk].es.fvw * sizeof(struct ice_fv_word); 4440 struct ice_chs_chg *tmp; 4441 4442 LIST_FOR_EACH_ENTRY(tmp, chgs, ice_chs_chg, list_entry) 4443 if (tmp->type == ICE_PTG_ES_ADD && tmp->add_prof) { 4444 u16 off = tmp->prof_id * hw->blk[blk].es.fvw; 4445 struct ice_pkg_es *p; 4446 u32 id; 4447 4448 id = ice_sect_id(blk, ICE_VEC_TBL); 4449 p = (struct ice_pkg_es *) 4450 ice_pkg_buf_alloc_section(bld, id, 4451 ice_struct_size(p, es, 4452 1) + 4453 vec_size - 4454 sizeof(p->es[0])); 4455 4456 if (!p) 4457 return ICE_ERR_MAX_LIMIT; 4458 4459 p->count = CPU_TO_LE16(1); 4460 p->offset = CPU_TO_LE16(tmp->prof_id); 4461 4462 ice_memcpy(p->es, &hw->blk[blk].es.t[off], vec_size, 4463 ICE_NONDMA_TO_NONDMA); 4464 } 4465 4466 return ICE_SUCCESS; 4467 } 4468 4469 /** 4470 * ice_prof_bld_tcam - build profile ID TCAM changes 4471 * @hw: pointer to the HW struct 4472 * @blk: hardware block 4473 * @bld: the update package buffer build to add to 4474 * @chgs: the list of changes to make in hardware 4475 */ 4476 static enum ice_status 4477 ice_prof_bld_tcam(struct ice_hw *hw, enum ice_block blk, 4478 struct ice_buf_build *bld, struct LIST_HEAD_TYPE *chgs) 4479 { 4480 struct ice_chs_chg *tmp; 4481 4482 LIST_FOR_EACH_ENTRY(tmp, chgs, ice_chs_chg, list_entry) 4483 if (tmp->type == ICE_TCAM_ADD && tmp->add_tcam_idx) { 4484 struct ice_prof_id_section *p; 4485 u32 id; 4486 4487 id = ice_sect_id(blk, ICE_PROF_TCAM); 4488 p = (struct ice_prof_id_section *) 4489 ice_pkg_buf_alloc_section(bld, id, 4490 ice_struct_size(p, 4491 entry, 4492 1)); 4493 4494 if (!p) 4495 return ICE_ERR_MAX_LIMIT; 4496 4497 p->count = CPU_TO_LE16(1); 4498 p->entry[0].addr = CPU_TO_LE16(tmp->tcam_idx); 4499 p->entry[0].prof_id = tmp->prof_id; 4500 4501 ice_memcpy(p->entry[0].key, 4502 &hw->blk[blk].prof.t[tmp->tcam_idx].key, 4503 sizeof(hw->blk[blk].prof.t->key), 4504 ICE_NONDMA_TO_NONDMA); 4505 } 4506 4507 return ICE_SUCCESS; 4508 } 4509 4510 /** 4511 * ice_prof_bld_xlt1 - build XLT1 changes 4512 * @blk: hardware block 4513 * @bld: the update package buffer build to add to 4514 * @chgs: the list of changes to make in hardware 4515 */ 4516 static enum ice_status 4517 ice_prof_bld_xlt1(enum ice_block blk, struct ice_buf_build *bld, 4518 struct LIST_HEAD_TYPE *chgs) 4519 { 4520 struct ice_chs_chg *tmp; 4521 4522 LIST_FOR_EACH_ENTRY(tmp, chgs, ice_chs_chg, list_entry) 4523 if (tmp->type == ICE_PTG_ES_ADD && tmp->add_ptg) { 4524 struct ice_xlt1_section *p; 4525 u32 id; 4526 4527 id = ice_sect_id(blk, ICE_XLT1); 4528 p = (struct ice_xlt1_section *) 4529 ice_pkg_buf_alloc_section(bld, id, 4530 ice_struct_size(p, 4531 value, 4532 1)); 4533 4534 if (!p) 4535 return ICE_ERR_MAX_LIMIT; 4536 4537 p->count = CPU_TO_LE16(1); 4538 p->offset = CPU_TO_LE16(tmp->ptype); 4539 p->value[0] = tmp->ptg; 4540 } 4541 4542 return ICE_SUCCESS; 4543 } 4544 4545 /** 4546 * ice_prof_bld_xlt2 - build XLT2 changes 4547 * @blk: hardware block 4548 * @bld: the update package buffer build to add to 4549 * @chgs: the list of changes to make in hardware 4550 */ 4551 static enum ice_status 4552 ice_prof_bld_xlt2(enum ice_block blk, struct ice_buf_build *bld, 4553 struct LIST_HEAD_TYPE *chgs) 4554 { 4555 struct ice_chs_chg *tmp; 4556 4557 LIST_FOR_EACH_ENTRY(tmp, chgs, ice_chs_chg, list_entry) { 4558 struct ice_xlt2_section *p; 4559 u32 id; 4560 4561 switch (tmp->type) { 4562 case ICE_VSIG_ADD: 4563 case ICE_VSI_MOVE: 4564 case ICE_VSIG_REM: 4565 id = ice_sect_id(blk, ICE_XLT2); 4566 p = (struct ice_xlt2_section *) 4567 ice_pkg_buf_alloc_section(bld, id, 4568 ice_struct_size(p, 4569 value, 4570 1)); 4571 4572 if (!p) 4573 return ICE_ERR_MAX_LIMIT; 4574 4575 p->count = CPU_TO_LE16(1); 4576 p->offset = CPU_TO_LE16(tmp->vsi); 4577 p->value[0] = CPU_TO_LE16(tmp->vsig); 4578 break; 4579 default: 4580 break; 4581 } 4582 } 4583 4584 return ICE_SUCCESS; 4585 } 4586 4587 /** 4588 * ice_upd_prof_hw - update hardware using the change list 4589 * @hw: pointer to the HW struct 4590 * @blk: hardware block 4591 * @chgs: the list of changes to make in hardware 4592 */ 4593 static enum ice_status 4594 ice_upd_prof_hw(struct ice_hw *hw, enum ice_block blk, 4595 struct LIST_HEAD_TYPE *chgs) 4596 { 4597 struct ice_buf_build *b; 4598 struct ice_chs_chg *tmp; 4599 enum ice_status status; 4600 u16 pkg_sects; 4601 u16 xlt1 = 0; 4602 u16 xlt2 = 0; 4603 u16 tcam = 0; 4604 u16 es = 0; 4605 u16 sects; 4606 4607 /* count number of sections we need */ 4608 LIST_FOR_EACH_ENTRY(tmp, chgs, ice_chs_chg, list_entry) { 4609 switch (tmp->type) { 4610 case ICE_PTG_ES_ADD: 4611 if (tmp->add_ptg) 4612 xlt1++; 4613 if (tmp->add_prof) 4614 es++; 4615 break; 4616 case ICE_TCAM_ADD: 4617 tcam++; 4618 break; 4619 case ICE_VSIG_ADD: 4620 case ICE_VSI_MOVE: 4621 case ICE_VSIG_REM: 4622 xlt2++; 4623 break; 4624 default: 4625 break; 4626 } 4627 } 4628 sects = xlt1 + xlt2 + tcam + es; 4629 4630 if (!sects) 4631 return ICE_SUCCESS; 4632 4633 /* Build update package buffer */ 4634 b = ice_pkg_buf_alloc(hw); 4635 if (!b) 4636 return ICE_ERR_NO_MEMORY; 4637 4638 status = ice_pkg_buf_reserve_section(b, sects); 4639 if (status) 4640 goto error_tmp; 4641 4642 /* Preserve order of table update: ES, TCAM, PTG, VSIG */ 4643 if (es) { 4644 status = ice_prof_bld_es(hw, blk, b, chgs); 4645 if (status) 4646 goto error_tmp; 4647 } 4648 4649 if (tcam) { 4650 status = ice_prof_bld_tcam(hw, blk, b, chgs); 4651 if (status) 4652 goto error_tmp; 4653 } 4654 4655 if (xlt1) { 4656 status = ice_prof_bld_xlt1(blk, b, chgs); 4657 if (status) 4658 goto error_tmp; 4659 } 4660 4661 if (xlt2) { 4662 status = ice_prof_bld_xlt2(blk, b, chgs); 4663 if (status) 4664 goto error_tmp; 4665 } 4666 4667 /* After package buffer build check if the section count in buffer is 4668 * non-zero and matches the number of sections detected for package 4669 * update. 4670 */ 4671 pkg_sects = ice_pkg_buf_get_active_sections(b); 4672 if (!pkg_sects || pkg_sects != sects) { 4673 status = ICE_ERR_INVAL_SIZE; 4674 goto error_tmp; 4675 } 4676 4677 /* update package */ 4678 status = ice_update_pkg(hw, ice_pkg_buf(b), 1); 4679 if (status == ICE_ERR_AQ_ERROR) 4680 ice_debug(hw, ICE_DBG_INIT, "Unable to update HW profile\n"); 4681 4682 error_tmp: 4683 ice_pkg_buf_free(hw, b); 4684 return status; 4685 } 4686 4687 /** 4688 * ice_update_fd_mask - set Flow Director Field Vector mask for a profile 4689 * @hw: pointer to the HW struct 4690 * @prof_id: profile ID 4691 * @mask_sel: mask select 4692 * 4693 * This function enable any of the masks selected by the mask select parameter 4694 * for the profile specified. 4695 */ 4696 static void ice_update_fd_mask(struct ice_hw *hw, u16 prof_id, u32 mask_sel) 4697 { 4698 wr32(hw, GLQF_FDMASK_SEL(prof_id), mask_sel); 4699 4700 ice_debug(hw, ICE_DBG_INIT, "fd mask(%d): %x = %x\n", prof_id, 4701 GLQF_FDMASK_SEL(prof_id), mask_sel); 4702 } 4703 4704 struct ice_fd_src_dst_pair { 4705 u8 prot_id; 4706 u8 count; 4707 u16 off; 4708 }; 4709 4710 static const struct ice_fd_src_dst_pair ice_fd_pairs[] = { 4711 /* These are defined in pairs */ 4712 { ICE_PROT_IPV4_OF_OR_S, 2, 12 }, 4713 { ICE_PROT_IPV4_OF_OR_S, 2, 16 }, 4714 4715 { ICE_PROT_IPV4_IL, 2, 12 }, 4716 { ICE_PROT_IPV4_IL, 2, 16 }, 4717 4718 { ICE_PROT_IPV6_OF_OR_S, 8, 8 }, 4719 { ICE_PROT_IPV6_OF_OR_S, 8, 24 }, 4720 4721 { ICE_PROT_IPV6_IL, 8, 8 }, 4722 { ICE_PROT_IPV6_IL, 8, 24 }, 4723 4724 { ICE_PROT_TCP_IL, 1, 0 }, 4725 { ICE_PROT_TCP_IL, 1, 2 }, 4726 4727 { ICE_PROT_UDP_OF, 1, 0 }, 4728 { ICE_PROT_UDP_OF, 1, 2 }, 4729 4730 { ICE_PROT_UDP_IL_OR_S, 1, 0 }, 4731 { ICE_PROT_UDP_IL_OR_S, 1, 2 }, 4732 4733 { ICE_PROT_SCTP_IL, 1, 0 }, 4734 { ICE_PROT_SCTP_IL, 1, 2 } 4735 }; 4736 4737 #define ICE_FD_SRC_DST_PAIR_COUNT ARRAY_SIZE(ice_fd_pairs) 4738 4739 /** 4740 * ice_update_fd_swap - set register appropriately for a FD FV extraction 4741 * @hw: pointer to the HW struct 4742 * @prof_id: profile ID 4743 * @es: extraction sequence (length of array is determined by the block) 4744 */ 4745 static enum ice_status 4746 ice_update_fd_swap(struct ice_hw *hw, u16 prof_id, struct ice_fv_word *es) 4747 { 4748 ice_declare_bitmap(pair_list, ICE_FD_SRC_DST_PAIR_COUNT); 4749 u8 pair_start[ICE_FD_SRC_DST_PAIR_COUNT] = { 0 }; 4750 #define ICE_FD_FV_NOT_FOUND (-2) 4751 s8 first_free = ICE_FD_FV_NOT_FOUND; 4752 u8 used[ICE_MAX_FV_WORDS] = { 0 }; 4753 s8 orig_free, si; 4754 u32 mask_sel = 0; 4755 u8 i, j, k; 4756 4757 ice_zero_bitmap(pair_list, ICE_FD_SRC_DST_PAIR_COUNT); 4758 4759 /* This code assumes that the Flow Director field vectors are assigned 4760 * from the end of the FV indexes working towards the zero index, that 4761 * only complete fields will be included and will be consecutive, and 4762 * that there are no gaps between valid indexes. 4763 */ 4764 4765 /* Determine swap fields present */ 4766 for (i = 0; i < hw->blk[ICE_BLK_FD].es.fvw; i++) { 4767 /* Find the first free entry, assuming right to left population. 4768 * This is where we can start adding additional pairs if needed. 4769 */ 4770 if (first_free == ICE_FD_FV_NOT_FOUND && es[i].prot_id != 4771 ICE_PROT_INVALID) 4772 first_free = i - 1; 4773 4774 for (j = 0; j < ICE_FD_SRC_DST_PAIR_COUNT; j++) 4775 if (es[i].prot_id == ice_fd_pairs[j].prot_id && 4776 es[i].off == ice_fd_pairs[j].off) { 4777 ice_set_bit(j, pair_list); 4778 pair_start[j] = i; 4779 } 4780 } 4781 4782 orig_free = first_free; 4783 4784 /* determine missing swap fields that need to be added */ 4785 for (i = 0; i < ICE_FD_SRC_DST_PAIR_COUNT; i += 2) { 4786 u8 bit1 = ice_is_bit_set(pair_list, i + 1); 4787 u8 bit0 = ice_is_bit_set(pair_list, i); 4788 4789 if (bit0 ^ bit1) { 4790 u8 index; 4791 4792 /* add the appropriate 'paired' entry */ 4793 if (!bit0) 4794 index = i; 4795 else 4796 index = i + 1; 4797 4798 /* check for room */ 4799 if (first_free + 1 < (s8)ice_fd_pairs[index].count) 4800 return ICE_ERR_MAX_LIMIT; 4801 4802 /* place in extraction sequence */ 4803 for (k = 0; k < ice_fd_pairs[index].count; k++) { 4804 es[first_free - k].prot_id = 4805 ice_fd_pairs[index].prot_id; 4806 es[first_free - k].off = 4807 ice_fd_pairs[index].off + (k * 2); 4808 4809 if (k > first_free) 4810 return ICE_ERR_OUT_OF_RANGE; 4811 4812 /* keep track of non-relevant fields */ 4813 mask_sel |= BIT(first_free - k); 4814 } 4815 4816 pair_start[index] = first_free; 4817 first_free -= ice_fd_pairs[index].count; 4818 } 4819 } 4820 4821 /* fill in the swap array */ 4822 si = hw->blk[ICE_BLK_FD].es.fvw - 1; 4823 while (si >= 0) { 4824 u8 indexes_used = 1; 4825 4826 /* assume flat at this index */ 4827 #define ICE_SWAP_VALID 0x80 4828 used[si] = si | ICE_SWAP_VALID; 4829 4830 if (orig_free == ICE_FD_FV_NOT_FOUND || si <= orig_free) { 4831 si -= indexes_used; 4832 continue; 4833 } 4834 4835 /* check for a swap location */ 4836 for (j = 0; j < ICE_FD_SRC_DST_PAIR_COUNT; j++) 4837 if (es[si].prot_id == ice_fd_pairs[j].prot_id && 4838 es[si].off == ice_fd_pairs[j].off) { 4839 u8 idx; 4840 4841 /* determine the appropriate matching field */ 4842 idx = j + ((j % 2) ? -1 : 1); 4843 4844 indexes_used = ice_fd_pairs[idx].count; 4845 for (k = 0; k < indexes_used; k++) { 4846 used[si - k] = (pair_start[idx] - k) | 4847 ICE_SWAP_VALID; 4848 } 4849 4850 break; 4851 } 4852 4853 si -= indexes_used; 4854 } 4855 4856 /* for each set of 4 swap and 4 inset indexes, write the appropriate 4857 * register 4858 */ 4859 for (j = 0; j < hw->blk[ICE_BLK_FD].es.fvw / 4; j++) { 4860 u32 raw_swap = 0; 4861 u32 raw_in = 0; 4862 4863 for (k = 0; k < 4; k++) { 4864 u8 idx; 4865 4866 idx = (j * 4) + k; 4867 if (used[idx] && !(mask_sel & BIT(idx))) { 4868 raw_swap |= used[idx] << (k * BITS_PER_BYTE); 4869 #define ICE_INSET_DFLT 0x9f 4870 raw_in |= ICE_INSET_DFLT << (k * BITS_PER_BYTE); 4871 } 4872 } 4873 4874 /* write the appropriate swap register set */ 4875 wr32(hw, GLQF_FDSWAP(prof_id, j), raw_swap); 4876 4877 ice_debug(hw, ICE_DBG_INIT, "swap wr(%d, %d): %x = %08x\n", 4878 prof_id, j, GLQF_FDSWAP(prof_id, j), raw_swap); 4879 4880 /* write the appropriate inset register set */ 4881 wr32(hw, GLQF_FDINSET(prof_id, j), raw_in); 4882 4883 ice_debug(hw, ICE_DBG_INIT, "inset wr(%d, %d): %x = %08x\n", 4884 prof_id, j, GLQF_FDINSET(prof_id, j), raw_in); 4885 } 4886 4887 /* initially clear the mask select for this profile */ 4888 ice_update_fd_mask(hw, prof_id, 0); 4889 4890 return ICE_SUCCESS; 4891 } 4892 4893 /* The entries here needs to match the order of enum ice_ptype_attrib */ 4894 static const struct ice_ptype_attrib_info ice_ptype_attributes[] = { 4895 { ICE_GTP_PDU_EH, ICE_GTP_PDU_FLAG_MASK }, 4896 { ICE_GTP_SESSION, ICE_GTP_FLAGS_MASK }, 4897 { ICE_GTP_DOWNLINK, ICE_GTP_FLAGS_MASK }, 4898 { ICE_GTP_UPLINK, ICE_GTP_FLAGS_MASK }, 4899 }; 4900 4901 /** 4902 * ice_get_ptype_attrib_info - get ptype attribute information 4903 * @type: attribute type 4904 * @info: pointer to variable to the attribute information 4905 */ 4906 static void 4907 ice_get_ptype_attrib_info(enum ice_ptype_attrib_type type, 4908 struct ice_ptype_attrib_info *info) 4909 { 4910 *info = ice_ptype_attributes[type]; 4911 } 4912 4913 /** 4914 * ice_add_prof_attrib - add any PTG with attributes to profile 4915 * @prof: pointer to the profile to which PTG entries will be added 4916 * @ptg: PTG to be added 4917 * @ptype: PTYPE that needs to be looked up 4918 * @attr: array of attributes that will be considered 4919 * @attr_cnt: number of elements in the attribute array 4920 */ 4921 static enum ice_status 4922 ice_add_prof_attrib(struct ice_prof_map *prof, u8 ptg, u16 ptype, 4923 const struct ice_ptype_attributes *attr, u16 attr_cnt) 4924 { 4925 bool found = false; 4926 u16 i; 4927 4928 for (i = 0; i < attr_cnt; i++) { 4929 if (attr[i].ptype == ptype) { 4930 found = true; 4931 4932 prof->ptg[prof->ptg_cnt] = ptg; 4933 ice_get_ptype_attrib_info(attr[i].attrib, 4934 &prof->attr[prof->ptg_cnt]); 4935 4936 if (++prof->ptg_cnt >= ICE_MAX_PTG_PER_PROFILE) 4937 return ICE_ERR_MAX_LIMIT; 4938 } 4939 } 4940 4941 if (!found) 4942 return ICE_ERR_DOES_NOT_EXIST; 4943 4944 return ICE_SUCCESS; 4945 } 4946 4947 /** 4948 * ice_add_prof - add profile 4949 * @hw: pointer to the HW struct 4950 * @blk: hardware block 4951 * @id: profile tracking ID 4952 * @ptypes: array of bitmaps indicating ptypes (ICE_FLOW_PTYPE_MAX bits) 4953 * @attr: array of attributes 4954 * @attr_cnt: number of elements in attrib array 4955 * @es: extraction sequence (length of array is determined by the block) 4956 * @masks: mask for extraction sequence 4957 * 4958 * This function registers a profile, which matches a set of PTYPES with a 4959 * particular extraction sequence. While the hardware profile is allocated 4960 * it will not be written until the first call to ice_add_flow that specifies 4961 * the ID value used here. 4962 */ 4963 enum ice_status 4964 ice_add_prof(struct ice_hw *hw, enum ice_block blk, u64 id, u8 ptypes[], 4965 const struct ice_ptype_attributes *attr, u16 attr_cnt, 4966 struct ice_fv_word *es, u16 *masks) 4967 { 4968 u32 bytes = DIVIDE_AND_ROUND_UP(ICE_FLOW_PTYPE_MAX, BITS_PER_BYTE); 4969 ice_declare_bitmap(ptgs_used, ICE_XLT1_CNT); 4970 struct ice_prof_map *prof; 4971 enum ice_status status; 4972 u8 byte = 0; 4973 u8 prof_id; 4974 4975 ice_zero_bitmap(ptgs_used, ICE_XLT1_CNT); 4976 4977 ice_acquire_lock(&hw->blk[blk].es.prof_map_lock); 4978 4979 /* search for existing profile */ 4980 status = ice_find_prof_id_with_mask(hw, blk, es, masks, &prof_id); 4981 if (status) { 4982 /* allocate profile ID */ 4983 status = ice_alloc_prof_id(hw, blk, &prof_id); 4984 if (status) 4985 goto err_ice_add_prof; 4986 if (blk == ICE_BLK_FD) { 4987 /* For Flow Director block, the extraction sequence may 4988 * need to be altered in the case where there are paired 4989 * fields that have no match. This is necessary because 4990 * for Flow Director, src and dest fields need to paired 4991 * for filter programming and these values are swapped 4992 * during Tx. 4993 */ 4994 status = ice_update_fd_swap(hw, prof_id, es); 4995 if (status) 4996 goto err_ice_add_prof; 4997 } 4998 status = ice_update_prof_masking(hw, blk, prof_id, masks); 4999 if (status) 5000 goto err_ice_add_prof; 5001 5002 /* and write new es */ 5003 ice_write_es(hw, blk, prof_id, es); 5004 } 5005 5006 ice_prof_inc_ref(hw, blk, prof_id); 5007 5008 /* add profile info */ 5009 5010 prof = (struct ice_prof_map *)ice_malloc(hw, sizeof(*prof)); 5011 if (!prof) 5012 goto err_ice_add_prof; 5013 5014 prof->profile_cookie = id; 5015 prof->prof_id = prof_id; 5016 prof->ptg_cnt = 0; 5017 prof->context = 0; 5018 5019 /* build list of ptgs */ 5020 while (bytes && prof->ptg_cnt < ICE_MAX_PTG_PER_PROFILE) { 5021 u8 bit; 5022 5023 if (!ptypes[byte]) { 5024 bytes--; 5025 byte++; 5026 continue; 5027 } 5028 5029 /* Examine 8 bits per byte */ 5030 ice_for_each_set_bit(bit, (ice_bitmap_t *)&ptypes[byte], 5031 BITS_PER_BYTE) { 5032 u16 ptype; 5033 u8 ptg; 5034 5035 ptype = byte * BITS_PER_BYTE + bit; 5036 5037 /* The package should place all ptypes in a non-zero 5038 * PTG, so the following call should never fail. 5039 */ 5040 if (ice_ptg_find_ptype(hw, blk, ptype, &ptg)) 5041 continue; 5042 5043 /* If PTG is already added, skip and continue */ 5044 if (ice_is_bit_set(ptgs_used, ptg)) 5045 continue; 5046 5047 ice_set_bit(ptg, ptgs_used); 5048 /* Check to see there are any attributes for this 5049 * ptype, and add them if found. 5050 */ 5051 status = ice_add_prof_attrib(prof, ptg, ptype, attr, 5052 attr_cnt); 5053 if (status == ICE_ERR_MAX_LIMIT) 5054 break; 5055 if (status) { 5056 /* This is simple a ptype/PTG with no 5057 * attribute 5058 */ 5059 prof->ptg[prof->ptg_cnt] = ptg; 5060 prof->attr[prof->ptg_cnt].flags = 0; 5061 prof->attr[prof->ptg_cnt].mask = 0; 5062 5063 if (++prof->ptg_cnt >= ICE_MAX_PTG_PER_PROFILE) 5064 break; 5065 } 5066 } 5067 5068 bytes--; 5069 byte++; 5070 } 5071 5072 LIST_ADD(&prof->list, &hw->blk[blk].es.prof_map); 5073 status = ICE_SUCCESS; 5074 5075 err_ice_add_prof: 5076 ice_release_lock(&hw->blk[blk].es.prof_map_lock); 5077 return status; 5078 } 5079 5080 /** 5081 * ice_search_prof_id - Search for a profile tracking ID 5082 * @hw: pointer to the HW struct 5083 * @blk: hardware block 5084 * @id: profile tracking ID 5085 * 5086 * This will search for a profile tracking ID which was previously added. 5087 * The profile map lock should be held before calling this function. 5088 */ 5089 struct ice_prof_map * 5090 ice_search_prof_id(struct ice_hw *hw, enum ice_block blk, u64 id) 5091 { 5092 struct ice_prof_map *entry = NULL; 5093 struct ice_prof_map *map; 5094 5095 LIST_FOR_EACH_ENTRY(map, &hw->blk[blk].es.prof_map, ice_prof_map, list) 5096 if (map->profile_cookie == id) { 5097 entry = map; 5098 break; 5099 } 5100 5101 return entry; 5102 } 5103 5104 /** 5105 * ice_vsig_prof_id_count - count profiles in a VSIG 5106 * @hw: pointer to the HW struct 5107 * @blk: hardware block 5108 * @vsig: VSIG to remove the profile from 5109 */ 5110 static u16 5111 ice_vsig_prof_id_count(struct ice_hw *hw, enum ice_block blk, u16 vsig) 5112 { 5113 u16 idx = vsig & ICE_VSIG_IDX_M, count = 0; 5114 struct ice_vsig_prof *p; 5115 5116 LIST_FOR_EACH_ENTRY(p, &hw->blk[blk].xlt2.vsig_tbl[idx].prop_lst, 5117 ice_vsig_prof, list) 5118 count++; 5119 5120 return count; 5121 } 5122 5123 /** 5124 * ice_rel_tcam_idx - release a TCAM index 5125 * @hw: pointer to the HW struct 5126 * @blk: hardware block 5127 * @idx: the index to release 5128 */ 5129 static enum ice_status 5130 ice_rel_tcam_idx(struct ice_hw *hw, enum ice_block blk, u16 idx) 5131 { 5132 /* Masks to invoke a never match entry */ 5133 u8 vl_msk[ICE_TCAM_KEY_VAL_SZ] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; 5134 u8 dc_msk[ICE_TCAM_KEY_VAL_SZ] = { 0xFE, 0xFF, 0xFF, 0xFF, 0xFF }; 5135 u8 nm_msk[ICE_TCAM_KEY_VAL_SZ] = { 0x01, 0x00, 0x00, 0x00, 0x00 }; 5136 enum ice_status status; 5137 5138 /* write the TCAM entry */ 5139 status = ice_tcam_write_entry(hw, blk, idx, 0, 0, 0, 0, 0, vl_msk, 5140 dc_msk, nm_msk); 5141 if (status) 5142 return status; 5143 5144 /* release the TCAM entry */ 5145 status = ice_free_tcam_ent(hw, blk, idx); 5146 5147 return status; 5148 } 5149 5150 /** 5151 * ice_rem_prof_id - remove one profile from a VSIG 5152 * @hw: pointer to the HW struct 5153 * @blk: hardware block 5154 * @prof: pointer to profile structure to remove 5155 */ 5156 static enum ice_status 5157 ice_rem_prof_id(struct ice_hw *hw, enum ice_block blk, 5158 struct ice_vsig_prof *prof) 5159 { 5160 enum ice_status status; 5161 u16 i; 5162 5163 for (i = 0; i < prof->tcam_count; i++) 5164 if (prof->tcam[i].in_use) { 5165 prof->tcam[i].in_use = false; 5166 status = ice_rel_tcam_idx(hw, blk, 5167 prof->tcam[i].tcam_idx); 5168 if (status) 5169 return ICE_ERR_HW_TABLE; 5170 } 5171 5172 return ICE_SUCCESS; 5173 } 5174 5175 /** 5176 * ice_rem_vsig - remove VSIG 5177 * @hw: pointer to the HW struct 5178 * @blk: hardware block 5179 * @vsig: the VSIG to remove 5180 * @chg: the change list 5181 */ 5182 static enum ice_status 5183 ice_rem_vsig(struct ice_hw *hw, enum ice_block blk, u16 vsig, 5184 struct LIST_HEAD_TYPE *chg) 5185 { 5186 u16 idx = vsig & ICE_VSIG_IDX_M; 5187 struct ice_vsig_vsi *vsi_cur; 5188 struct ice_vsig_prof *d, *t; 5189 enum ice_status status; 5190 5191 /* remove TCAM entries */ 5192 LIST_FOR_EACH_ENTRY_SAFE(d, t, 5193 &hw->blk[blk].xlt2.vsig_tbl[idx].prop_lst, 5194 ice_vsig_prof, list) { 5195 status = ice_rem_prof_id(hw, blk, d); 5196 if (status) 5197 return status; 5198 5199 LIST_DEL(&d->list); 5200 ice_free(hw, d); 5201 } 5202 5203 /* Move all VSIS associated with this VSIG to the default VSIG */ 5204 vsi_cur = hw->blk[blk].xlt2.vsig_tbl[idx].first_vsi; 5205 /* If the VSIG has at least 1 VSI then iterate through the list 5206 * and remove the VSIs before deleting the group. 5207 */ 5208 if (vsi_cur) 5209 do { 5210 struct ice_vsig_vsi *tmp = vsi_cur->next_vsi; 5211 struct ice_chs_chg *p; 5212 5213 p = (struct ice_chs_chg *)ice_malloc(hw, sizeof(*p)); 5214 if (!p) 5215 return ICE_ERR_NO_MEMORY; 5216 5217 p->type = ICE_VSIG_REM; 5218 p->orig_vsig = vsig; 5219 p->vsig = ICE_DEFAULT_VSIG; 5220 p->vsi = vsi_cur - hw->blk[blk].xlt2.vsis; 5221 5222 LIST_ADD(&p->list_entry, chg); 5223 5224 vsi_cur = tmp; 5225 } while (vsi_cur); 5226 5227 return ice_vsig_free(hw, blk, vsig); 5228 } 5229 5230 /** 5231 * ice_rem_prof_id_vsig - remove a specific profile from a VSIG 5232 * @hw: pointer to the HW struct 5233 * @blk: hardware block 5234 * @vsig: VSIG to remove the profile from 5235 * @hdl: profile handle indicating which profile to remove 5236 * @chg: list to receive a record of changes 5237 */ 5238 static enum ice_status 5239 ice_rem_prof_id_vsig(struct ice_hw *hw, enum ice_block blk, u16 vsig, u64 hdl, 5240 struct LIST_HEAD_TYPE *chg) 5241 { 5242 u16 idx = vsig & ICE_VSIG_IDX_M; 5243 struct ice_vsig_prof *p, *t; 5244 enum ice_status status; 5245 5246 LIST_FOR_EACH_ENTRY_SAFE(p, t, 5247 &hw->blk[blk].xlt2.vsig_tbl[idx].prop_lst, 5248 ice_vsig_prof, list) 5249 if (p->profile_cookie == hdl) { 5250 if (ice_vsig_prof_id_count(hw, blk, vsig) == 1) 5251 /* this is the last profile, remove the VSIG */ 5252 return ice_rem_vsig(hw, blk, vsig, chg); 5253 5254 status = ice_rem_prof_id(hw, blk, p); 5255 if (!status) { 5256 LIST_DEL(&p->list); 5257 ice_free(hw, p); 5258 } 5259 return status; 5260 } 5261 5262 return ICE_ERR_DOES_NOT_EXIST; 5263 } 5264 5265 /** 5266 * ice_rem_flow_all - remove all flows with a particular profile 5267 * @hw: pointer to the HW struct 5268 * @blk: hardware block 5269 * @id: profile tracking ID 5270 */ 5271 static enum ice_status 5272 ice_rem_flow_all(struct ice_hw *hw, enum ice_block blk, u64 id) 5273 { 5274 struct ice_chs_chg *del, *tmp; 5275 struct LIST_HEAD_TYPE chg; 5276 enum ice_status status; 5277 u16 i; 5278 5279 INIT_LIST_HEAD(&chg); 5280 5281 for (i = 1; i < ICE_MAX_VSIGS; i++) 5282 if (hw->blk[blk].xlt2.vsig_tbl[i].in_use) { 5283 if (ice_has_prof_vsig(hw, blk, i, id)) { 5284 status = ice_rem_prof_id_vsig(hw, blk, i, id, 5285 &chg); 5286 if (status) 5287 goto err_ice_rem_flow_all; 5288 } 5289 } 5290 5291 status = ice_upd_prof_hw(hw, blk, &chg); 5292 5293 err_ice_rem_flow_all: 5294 LIST_FOR_EACH_ENTRY_SAFE(del, tmp, &chg, ice_chs_chg, list_entry) { 5295 LIST_DEL(&del->list_entry); 5296 ice_free(hw, del); 5297 } 5298 5299 return status; 5300 } 5301 5302 /** 5303 * ice_rem_prof - remove profile 5304 * @hw: pointer to the HW struct 5305 * @blk: hardware block 5306 * @id: profile tracking ID 5307 * 5308 * This will remove the profile specified by the ID parameter, which was 5309 * previously created through ice_add_prof. If any existing entries 5310 * are associated with this profile, they will be removed as well. 5311 */ 5312 enum ice_status ice_rem_prof(struct ice_hw *hw, enum ice_block blk, u64 id) 5313 { 5314 struct ice_prof_map *pmap; 5315 enum ice_status status; 5316 5317 ice_acquire_lock(&hw->blk[blk].es.prof_map_lock); 5318 5319 pmap = ice_search_prof_id(hw, blk, id); 5320 if (!pmap) { 5321 status = ICE_ERR_DOES_NOT_EXIST; 5322 goto err_ice_rem_prof; 5323 } 5324 5325 /* remove all flows with this profile */ 5326 status = ice_rem_flow_all(hw, blk, pmap->profile_cookie); 5327 if (status) 5328 goto err_ice_rem_prof; 5329 5330 /* dereference profile, and possibly remove */ 5331 ice_prof_dec_ref(hw, blk, pmap->prof_id); 5332 5333 LIST_DEL(&pmap->list); 5334 ice_free(hw, pmap); 5335 5336 err_ice_rem_prof: 5337 ice_release_lock(&hw->blk[blk].es.prof_map_lock); 5338 return status; 5339 } 5340 5341 /** 5342 * ice_get_prof - get profile 5343 * @hw: pointer to the HW struct 5344 * @blk: hardware block 5345 * @hdl: profile handle 5346 * @chg: change list 5347 */ 5348 static enum ice_status 5349 ice_get_prof(struct ice_hw *hw, enum ice_block blk, u64 hdl, 5350 struct LIST_HEAD_TYPE *chg) 5351 { 5352 enum ice_status status = ICE_SUCCESS; 5353 struct ice_prof_map *map; 5354 struct ice_chs_chg *p; 5355 u16 i; 5356 5357 ice_acquire_lock(&hw->blk[blk].es.prof_map_lock); 5358 /* Get the details on the profile specified by the handle ID */ 5359 map = ice_search_prof_id(hw, blk, hdl); 5360 if (!map) { 5361 status = ICE_ERR_DOES_NOT_EXIST; 5362 goto err_ice_get_prof; 5363 } 5364 5365 for (i = 0; i < map->ptg_cnt; i++) 5366 if (!hw->blk[blk].es.written[map->prof_id]) { 5367 /* add ES to change list */ 5368 p = (struct ice_chs_chg *)ice_malloc(hw, sizeof(*p)); 5369 if (!p) { 5370 status = ICE_ERR_NO_MEMORY; 5371 goto err_ice_get_prof; 5372 } 5373 5374 p->type = ICE_PTG_ES_ADD; 5375 p->ptype = 0; 5376 p->ptg = map->ptg[i]; 5377 p->attr = map->attr[i]; 5378 p->add_ptg = 0; 5379 5380 p->add_prof = 1; 5381 p->prof_id = map->prof_id; 5382 5383 hw->blk[blk].es.written[map->prof_id] = true; 5384 5385 LIST_ADD(&p->list_entry, chg); 5386 } 5387 5388 err_ice_get_prof: 5389 ice_release_lock(&hw->blk[blk].es.prof_map_lock); 5390 /* let caller clean up the change list */ 5391 return status; 5392 } 5393 5394 /** 5395 * ice_get_profs_vsig - get a copy of the list of profiles from a VSIG 5396 * @hw: pointer to the HW struct 5397 * @blk: hardware block 5398 * @vsig: VSIG from which to copy the list 5399 * @lst: output list 5400 * 5401 * This routine makes a copy of the list of profiles in the specified VSIG. 5402 */ 5403 static enum ice_status 5404 ice_get_profs_vsig(struct ice_hw *hw, enum ice_block blk, u16 vsig, 5405 struct LIST_HEAD_TYPE *lst) 5406 { 5407 struct ice_vsig_prof *ent1, *ent2; 5408 u16 idx = vsig & ICE_VSIG_IDX_M; 5409 5410 LIST_FOR_EACH_ENTRY(ent1, &hw->blk[blk].xlt2.vsig_tbl[idx].prop_lst, 5411 ice_vsig_prof, list) { 5412 struct ice_vsig_prof *p; 5413 5414 /* copy to the input list */ 5415 p = (struct ice_vsig_prof *)ice_memdup(hw, ent1, sizeof(*p), 5416 ICE_NONDMA_TO_NONDMA); 5417 if (!p) 5418 goto err_ice_get_profs_vsig; 5419 5420 LIST_ADD_TAIL(&p->list, lst); 5421 } 5422 5423 return ICE_SUCCESS; 5424 5425 err_ice_get_profs_vsig: 5426 LIST_FOR_EACH_ENTRY_SAFE(ent1, ent2, lst, ice_vsig_prof, list) { 5427 LIST_DEL(&ent1->list); 5428 ice_free(hw, ent1); 5429 } 5430 5431 return ICE_ERR_NO_MEMORY; 5432 } 5433 5434 /** 5435 * ice_add_prof_to_lst - add profile entry to a list 5436 * @hw: pointer to the HW struct 5437 * @blk: hardware block 5438 * @lst: the list to be added to 5439 * @hdl: profile handle of entry to add 5440 */ 5441 static enum ice_status 5442 ice_add_prof_to_lst(struct ice_hw *hw, enum ice_block blk, 5443 struct LIST_HEAD_TYPE *lst, u64 hdl) 5444 { 5445 enum ice_status status = ICE_SUCCESS; 5446 struct ice_prof_map *map; 5447 struct ice_vsig_prof *p; 5448 u16 i; 5449 5450 ice_acquire_lock(&hw->blk[blk].es.prof_map_lock); 5451 map = ice_search_prof_id(hw, blk, hdl); 5452 if (!map) { 5453 status = ICE_ERR_DOES_NOT_EXIST; 5454 goto err_ice_add_prof_to_lst; 5455 } 5456 5457 p = (struct ice_vsig_prof *)ice_malloc(hw, sizeof(*p)); 5458 if (!p) { 5459 status = ICE_ERR_NO_MEMORY; 5460 goto err_ice_add_prof_to_lst; 5461 } 5462 5463 p->profile_cookie = map->profile_cookie; 5464 p->prof_id = map->prof_id; 5465 p->tcam_count = map->ptg_cnt; 5466 5467 for (i = 0; i < map->ptg_cnt; i++) { 5468 p->tcam[i].prof_id = map->prof_id; 5469 p->tcam[i].tcam_idx = ICE_INVALID_TCAM; 5470 p->tcam[i].ptg = map->ptg[i]; 5471 p->tcam[i].attr = map->attr[i]; 5472 } 5473 5474 LIST_ADD(&p->list, lst); 5475 5476 err_ice_add_prof_to_lst: 5477 ice_release_lock(&hw->blk[blk].es.prof_map_lock); 5478 return status; 5479 } 5480 5481 /** 5482 * ice_move_vsi - move VSI to another VSIG 5483 * @hw: pointer to the HW struct 5484 * @blk: hardware block 5485 * @vsi: the VSI to move 5486 * @vsig: the VSIG to move the VSI to 5487 * @chg: the change list 5488 */ 5489 static enum ice_status 5490 ice_move_vsi(struct ice_hw *hw, enum ice_block blk, u16 vsi, u16 vsig, 5491 struct LIST_HEAD_TYPE *chg) 5492 { 5493 enum ice_status status; 5494 struct ice_chs_chg *p; 5495 u16 orig_vsig; 5496 5497 p = (struct ice_chs_chg *)ice_malloc(hw, sizeof(*p)); 5498 if (!p) 5499 return ICE_ERR_NO_MEMORY; 5500 5501 status = ice_vsig_find_vsi(hw, blk, vsi, &orig_vsig); 5502 if (!status) 5503 status = ice_vsig_add_mv_vsi(hw, blk, vsi, vsig); 5504 5505 if (status) { 5506 ice_free(hw, p); 5507 return status; 5508 } 5509 5510 p->type = ICE_VSI_MOVE; 5511 p->vsi = vsi; 5512 p->orig_vsig = orig_vsig; 5513 p->vsig = vsig; 5514 5515 LIST_ADD(&p->list_entry, chg); 5516 5517 return ICE_SUCCESS; 5518 } 5519 5520 /** 5521 * ice_set_tcam_flags - set TCAM flag don't care mask 5522 * @mask: mask for flags 5523 * @dc_mask: pointer to the don't care mask 5524 */ 5525 static void ice_set_tcam_flags(u16 mask, u8 dc_mask[ICE_TCAM_KEY_VAL_SZ]) 5526 { 5527 u16 *flag_word; 5528 5529 /* flags are lowest u16 */ 5530 flag_word = (u16 *)dc_mask; 5531 *flag_word = ~mask; 5532 } 5533 5534 /** 5535 * ice_rem_chg_tcam_ent - remove a specific TCAM entry from change list 5536 * @hw: pointer to the HW struct 5537 * @idx: the index of the TCAM entry to remove 5538 * @chg: the list of change structures to search 5539 */ 5540 static void 5541 ice_rem_chg_tcam_ent(struct ice_hw *hw, u16 idx, struct LIST_HEAD_TYPE *chg) 5542 { 5543 struct ice_chs_chg *pos, *tmp; 5544 5545 LIST_FOR_EACH_ENTRY_SAFE(tmp, pos, chg, ice_chs_chg, list_entry) 5546 if (tmp->type == ICE_TCAM_ADD && tmp->tcam_idx == idx) { 5547 LIST_DEL(&tmp->list_entry); 5548 ice_free(hw, tmp); 5549 } 5550 } 5551 5552 /** 5553 * ice_prof_tcam_ena_dis - add enable or disable TCAM change 5554 * @hw: pointer to the HW struct 5555 * @blk: hardware block 5556 * @enable: true to enable, false to disable 5557 * @vsig: the VSIG of the TCAM entry 5558 * @tcam: pointer the TCAM info structure of the TCAM to disable 5559 * @chg: the change list 5560 * 5561 * This function appends an enable or disable TCAM entry in the change log 5562 */ 5563 static enum ice_status 5564 ice_prof_tcam_ena_dis(struct ice_hw *hw, enum ice_block blk, bool enable, 5565 u16 vsig, struct ice_tcam_inf *tcam, 5566 struct LIST_HEAD_TYPE *chg) 5567 { 5568 enum ice_status status; 5569 struct ice_chs_chg *p; 5570 5571 u8 vl_msk[ICE_TCAM_KEY_VAL_SZ] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; 5572 u8 dc_msk[ICE_TCAM_KEY_VAL_SZ] = { 0xFF, 0xFF, 0x00, 0x00, 0x00 }; 5573 u8 nm_msk[ICE_TCAM_KEY_VAL_SZ] = { 0x00, 0x00, 0x00, 0x00, 0x00 }; 5574 5575 /* if disabling, free the TCAM */ 5576 if (!enable) { 5577 status = ice_rel_tcam_idx(hw, blk, tcam->tcam_idx); 5578 5579 /* if we have already created a change for this TCAM entry, then 5580 * we need to remove that entry, in order to prevent writing to 5581 * a TCAM entry we no longer will have ownership of. 5582 */ 5583 ice_rem_chg_tcam_ent(hw, tcam->tcam_idx, chg); 5584 tcam->tcam_idx = 0; 5585 tcam->in_use = 0; 5586 return status; 5587 } 5588 5589 /* for re-enabling, reallocate a TCAM */ 5590 /* for entries with empty attribute masks, allocate entry from 5591 * the bottom of the TCAM table; otherwise, allocate from the 5592 * top of the table in order to give it higher priority 5593 */ 5594 status = ice_alloc_tcam_ent(hw, blk, tcam->attr.mask == 0, 5595 &tcam->tcam_idx); 5596 if (status) 5597 return status; 5598 5599 /* add TCAM to change list */ 5600 p = (struct ice_chs_chg *)ice_malloc(hw, sizeof(*p)); 5601 if (!p) 5602 return ICE_ERR_NO_MEMORY; 5603 5604 /* set don't care masks for TCAM flags */ 5605 ice_set_tcam_flags(tcam->attr.mask, dc_msk); 5606 5607 status = ice_tcam_write_entry(hw, blk, tcam->tcam_idx, tcam->prof_id, 5608 tcam->ptg, vsig, 0, tcam->attr.flags, 5609 vl_msk, dc_msk, nm_msk); 5610 if (status) 5611 goto err_ice_prof_tcam_ena_dis; 5612 5613 tcam->in_use = 1; 5614 5615 p->type = ICE_TCAM_ADD; 5616 p->add_tcam_idx = true; 5617 p->prof_id = tcam->prof_id; 5618 p->ptg = tcam->ptg; 5619 p->vsig = 0; 5620 p->tcam_idx = tcam->tcam_idx; 5621 5622 /* log change */ 5623 LIST_ADD(&p->list_entry, chg); 5624 5625 return ICE_SUCCESS; 5626 5627 err_ice_prof_tcam_ena_dis: 5628 ice_free(hw, p); 5629 return status; 5630 } 5631 5632 /** 5633 * ice_ptg_attr_in_use - determine if PTG and attribute pair is in use 5634 * @ptg_attr: pointer to the PTG and attribute pair to check 5635 * @ptgs_used: bitmap that denotes which PTGs are in use 5636 * @attr_used: array of PTG and attributes pairs already used 5637 * @attr_cnt: count of entries in the attr_used array 5638 */ 5639 static bool 5640 ice_ptg_attr_in_use(struct ice_tcam_inf *ptg_attr, ice_bitmap_t *ptgs_used, 5641 struct ice_tcam_inf *attr_used[], u16 attr_cnt) 5642 { 5643 u16 i; 5644 5645 if (!ice_is_bit_set(ptgs_used, ptg_attr->ptg)) 5646 return false; 5647 5648 /* the PTG is used, so now look for correct attributes */ 5649 for (i = 0; i < attr_cnt; i++) 5650 if (attr_used[i]->ptg == ptg_attr->ptg && 5651 attr_used[i]->attr.flags == ptg_attr->attr.flags && 5652 attr_used[i]->attr.mask == ptg_attr->attr.mask) 5653 return true; 5654 5655 return false; 5656 } 5657 5658 /** 5659 * ice_adj_prof_priorities - adjust profile based on priorities 5660 * @hw: pointer to the HW struct 5661 * @blk: hardware block 5662 * @vsig: the VSIG for which to adjust profile priorities 5663 * @chg: the change list 5664 */ 5665 static enum ice_status 5666 ice_adj_prof_priorities(struct ice_hw *hw, enum ice_block blk, u16 vsig, 5667 struct LIST_HEAD_TYPE *chg) 5668 { 5669 ice_declare_bitmap(ptgs_used, ICE_XLT1_CNT); 5670 struct ice_tcam_inf **attr_used; 5671 enum ice_status status = ICE_SUCCESS; 5672 struct ice_vsig_prof *t; 5673 u16 attr_used_cnt = 0; 5674 u16 idx; 5675 5676 #define ICE_MAX_PTG_ATTRS 1024 5677 attr_used = (struct ice_tcam_inf **)ice_calloc(hw, ICE_MAX_PTG_ATTRS, 5678 sizeof(*attr_used)); 5679 if (!attr_used) 5680 return ICE_ERR_NO_MEMORY; 5681 5682 ice_zero_bitmap(ptgs_used, ICE_XLT1_CNT); 5683 idx = vsig & ICE_VSIG_IDX_M; 5684 5685 /* Priority is based on the order in which the profiles are added. The 5686 * newest added profile has highest priority and the oldest added 5687 * profile has the lowest priority. Since the profile property list for 5688 * a VSIG is sorted from newest to oldest, this code traverses the list 5689 * in order and enables the first of each PTG that it finds (that is not 5690 * already enabled); it also disables any duplicate PTGs that it finds 5691 * in the older profiles (that are currently enabled). 5692 */ 5693 5694 LIST_FOR_EACH_ENTRY(t, &hw->blk[blk].xlt2.vsig_tbl[idx].prop_lst, 5695 ice_vsig_prof, list) { 5696 u16 i; 5697 5698 for (i = 0; i < t->tcam_count; i++) { 5699 bool used; 5700 5701 /* Scan the priorities from newest to oldest. 5702 * Make sure that the newest profiles take priority. 5703 */ 5704 used = ice_ptg_attr_in_use(&t->tcam[i], ptgs_used, 5705 attr_used, attr_used_cnt); 5706 5707 if (used && t->tcam[i].in_use) { 5708 /* need to mark this PTG as never match, as it 5709 * was already in use and therefore duplicate 5710 * (and lower priority) 5711 */ 5712 status = ice_prof_tcam_ena_dis(hw, blk, false, 5713 vsig, 5714 &t->tcam[i], 5715 chg); 5716 if (status) 5717 goto err_ice_adj_prof_priorities; 5718 } else if (!used && !t->tcam[i].in_use) { 5719 /* need to enable this PTG, as it in not in use 5720 * and not enabled (highest priority) 5721 */ 5722 status = ice_prof_tcam_ena_dis(hw, blk, true, 5723 vsig, 5724 &t->tcam[i], 5725 chg); 5726 if (status) 5727 goto err_ice_adj_prof_priorities; 5728 } 5729 5730 /* keep track of used ptgs */ 5731 ice_set_bit(t->tcam[i].ptg, ptgs_used); 5732 if (attr_used_cnt < ICE_MAX_PTG_ATTRS) 5733 attr_used[attr_used_cnt++] = &t->tcam[i]; 5734 else 5735 ice_debug(hw, ICE_DBG_INIT, "Warn: ICE_MAX_PTG_ATTRS exceeded\n"); 5736 } 5737 } 5738 5739 err_ice_adj_prof_priorities: 5740 ice_free(hw, attr_used); 5741 return status; 5742 } 5743 5744 /** 5745 * ice_add_prof_id_vsig - add profile to VSIG 5746 * @hw: pointer to the HW struct 5747 * @blk: hardware block 5748 * @vsig: the VSIG to which this profile is to be added 5749 * @hdl: the profile handle indicating the profile to add 5750 * @rev: true to add entries to the end of the list 5751 * @chg: the change list 5752 */ 5753 static enum ice_status 5754 ice_add_prof_id_vsig(struct ice_hw *hw, enum ice_block blk, u16 vsig, u64 hdl, 5755 bool rev, struct LIST_HEAD_TYPE *chg) 5756 { 5757 /* Masks that ignore flags */ 5758 u8 vl_msk[ICE_TCAM_KEY_VAL_SZ] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; 5759 u8 dc_msk[ICE_TCAM_KEY_VAL_SZ] = { 0xFF, 0xFF, 0x00, 0x00, 0x00 }; 5760 u8 nm_msk[ICE_TCAM_KEY_VAL_SZ] = { 0x00, 0x00, 0x00, 0x00, 0x00 }; 5761 enum ice_status status = ICE_SUCCESS; 5762 struct ice_prof_map *map; 5763 struct ice_vsig_prof *t; 5764 struct ice_chs_chg *p; 5765 u16 vsig_idx, i; 5766 5767 /* Error, if this VSIG already has this profile */ 5768 if (ice_has_prof_vsig(hw, blk, vsig, hdl)) 5769 return ICE_ERR_ALREADY_EXISTS; 5770 5771 /* new VSIG profile structure */ 5772 t = (struct ice_vsig_prof *)ice_malloc(hw, sizeof(*t)); 5773 if (!t) 5774 return ICE_ERR_NO_MEMORY; 5775 5776 ice_acquire_lock(&hw->blk[blk].es.prof_map_lock); 5777 /* Get the details on the profile specified by the handle ID */ 5778 map = ice_search_prof_id(hw, blk, hdl); 5779 if (!map) { 5780 status = ICE_ERR_DOES_NOT_EXIST; 5781 goto err_ice_add_prof_id_vsig; 5782 } 5783 5784 t->profile_cookie = map->profile_cookie; 5785 t->prof_id = map->prof_id; 5786 t->tcam_count = map->ptg_cnt; 5787 5788 /* create TCAM entries */ 5789 for (i = 0; i < map->ptg_cnt; i++) { 5790 u16 tcam_idx; 5791 5792 /* add TCAM to change list */ 5793 p = (struct ice_chs_chg *)ice_malloc(hw, sizeof(*p)); 5794 if (!p) { 5795 status = ICE_ERR_NO_MEMORY; 5796 goto err_ice_add_prof_id_vsig; 5797 } 5798 5799 /* allocate the TCAM entry index */ 5800 /* for entries with empty attribute masks, allocate entry from 5801 * the bottom of the TCAM table; otherwise, allocate from the 5802 * top of the table in order to give it higher priority 5803 */ 5804 status = ice_alloc_tcam_ent(hw, blk, map->attr[i].mask == 0, 5805 &tcam_idx); 5806 if (status) { 5807 ice_free(hw, p); 5808 goto err_ice_add_prof_id_vsig; 5809 } 5810 5811 t->tcam[i].ptg = map->ptg[i]; 5812 t->tcam[i].prof_id = map->prof_id; 5813 t->tcam[i].tcam_idx = tcam_idx; 5814 t->tcam[i].attr = map->attr[i]; 5815 t->tcam[i].in_use = true; 5816 5817 p->type = ICE_TCAM_ADD; 5818 p->add_tcam_idx = true; 5819 p->prof_id = t->tcam[i].prof_id; 5820 p->ptg = t->tcam[i].ptg; 5821 p->vsig = vsig; 5822 p->tcam_idx = t->tcam[i].tcam_idx; 5823 5824 /* set don't care masks for TCAM flags */ 5825 ice_set_tcam_flags(t->tcam[i].attr.mask, dc_msk); 5826 5827 /* write the TCAM entry */ 5828 status = ice_tcam_write_entry(hw, blk, t->tcam[i].tcam_idx, 5829 t->tcam[i].prof_id, 5830 t->tcam[i].ptg, vsig, 0, 5831 t->tcam[i].attr.flags, vl_msk, 5832 dc_msk, nm_msk); 5833 if (status) { 5834 ice_free(hw, p); 5835 goto err_ice_add_prof_id_vsig; 5836 } 5837 5838 /* log change */ 5839 LIST_ADD(&p->list_entry, chg); 5840 } 5841 5842 /* add profile to VSIG */ 5843 vsig_idx = vsig & ICE_VSIG_IDX_M; 5844 if (rev) 5845 LIST_ADD_TAIL(&t->list, 5846 &hw->blk[blk].xlt2.vsig_tbl[vsig_idx].prop_lst); 5847 else 5848 LIST_ADD(&t->list, 5849 &hw->blk[blk].xlt2.vsig_tbl[vsig_idx].prop_lst); 5850 5851 ice_release_lock(&hw->blk[blk].es.prof_map_lock); 5852 return status; 5853 5854 err_ice_add_prof_id_vsig: 5855 ice_release_lock(&hw->blk[blk].es.prof_map_lock); 5856 /* let caller clean up the change list */ 5857 ice_free(hw, t); 5858 return status; 5859 } 5860 5861 /** 5862 * ice_create_prof_id_vsig - add a new VSIG with a single profile 5863 * @hw: pointer to the HW struct 5864 * @blk: hardware block 5865 * @vsi: the initial VSI that will be in VSIG 5866 * @hdl: the profile handle of the profile that will be added to the VSIG 5867 * @chg: the change list 5868 */ 5869 static enum ice_status 5870 ice_create_prof_id_vsig(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl, 5871 struct LIST_HEAD_TYPE *chg) 5872 { 5873 enum ice_status status; 5874 struct ice_chs_chg *p; 5875 u16 new_vsig; 5876 5877 p = (struct ice_chs_chg *)ice_malloc(hw, sizeof(*p)); 5878 if (!p) 5879 return ICE_ERR_NO_MEMORY; 5880 5881 new_vsig = ice_vsig_alloc(hw, blk); 5882 if (!new_vsig) { 5883 status = ICE_ERR_HW_TABLE; 5884 goto err_ice_create_prof_id_vsig; 5885 } 5886 5887 status = ice_move_vsi(hw, blk, vsi, new_vsig, chg); 5888 if (status) 5889 goto err_ice_create_prof_id_vsig; 5890 5891 status = ice_add_prof_id_vsig(hw, blk, new_vsig, hdl, false, chg); 5892 if (status) 5893 goto err_ice_create_prof_id_vsig; 5894 5895 p->type = ICE_VSIG_ADD; 5896 p->vsi = vsi; 5897 p->orig_vsig = ICE_DEFAULT_VSIG; 5898 p->vsig = new_vsig; 5899 5900 LIST_ADD(&p->list_entry, chg); 5901 5902 return ICE_SUCCESS; 5903 5904 err_ice_create_prof_id_vsig: 5905 /* let caller clean up the change list */ 5906 ice_free(hw, p); 5907 return status; 5908 } 5909 5910 /** 5911 * ice_create_vsig_from_lst - create a new VSIG with a list of profiles 5912 * @hw: pointer to the HW struct 5913 * @blk: hardware block 5914 * @vsi: the initial VSI that will be in VSIG 5915 * @lst: the list of profile that will be added to the VSIG 5916 * @new_vsig: return of new VSIG 5917 * @chg: the change list 5918 */ 5919 static enum ice_status 5920 ice_create_vsig_from_lst(struct ice_hw *hw, enum ice_block blk, u16 vsi, 5921 struct LIST_HEAD_TYPE *lst, u16 *new_vsig, 5922 struct LIST_HEAD_TYPE *chg) 5923 { 5924 struct ice_vsig_prof *t; 5925 enum ice_status status; 5926 u16 vsig; 5927 5928 vsig = ice_vsig_alloc(hw, blk); 5929 if (!vsig) 5930 return ICE_ERR_HW_TABLE; 5931 5932 status = ice_move_vsi(hw, blk, vsi, vsig, chg); 5933 if (status) 5934 return status; 5935 5936 LIST_FOR_EACH_ENTRY(t, lst, ice_vsig_prof, list) { 5937 /* Reverse the order here since we are copying the list */ 5938 status = ice_add_prof_id_vsig(hw, blk, vsig, t->profile_cookie, 5939 true, chg); 5940 if (status) 5941 return status; 5942 } 5943 5944 *new_vsig = vsig; 5945 5946 return ICE_SUCCESS; 5947 } 5948 5949 /** 5950 * ice_find_prof_vsig - find a VSIG with a specific profile handle 5951 * @hw: pointer to the HW struct 5952 * @blk: hardware block 5953 * @hdl: the profile handle of the profile to search for 5954 * @vsig: returns the VSIG with the matching profile 5955 */ 5956 static bool 5957 ice_find_prof_vsig(struct ice_hw *hw, enum ice_block blk, u64 hdl, u16 *vsig) 5958 { 5959 struct ice_vsig_prof *t; 5960 struct LIST_HEAD_TYPE lst; 5961 enum ice_status status; 5962 5963 INIT_LIST_HEAD(&lst); 5964 5965 t = (struct ice_vsig_prof *)ice_malloc(hw, sizeof(*t)); 5966 if (!t) 5967 return false; 5968 5969 t->profile_cookie = hdl; 5970 LIST_ADD(&t->list, &lst); 5971 5972 status = ice_find_dup_props_vsig(hw, blk, &lst, vsig); 5973 5974 LIST_DEL(&t->list); 5975 ice_free(hw, t); 5976 5977 return status == ICE_SUCCESS; 5978 } 5979 5980 /** 5981 * ice_add_vsi_flow - add VSI flow 5982 * @hw: pointer to the HW struct 5983 * @blk: hardware block 5984 * @vsi: input VSI 5985 * @vsig: target VSIG to include the input VSI 5986 * 5987 * Calling this function will add the VSI to a given VSIG and 5988 * update the HW tables accordingly. This call can be used to 5989 * add multiple VSIs to a VSIG if we know beforehand that those 5990 * VSIs have the same characteristics of the VSIG. This will 5991 * save time in generating a new VSIG and TCAMs till a match is 5992 * found and subsequent rollback when a matching VSIG is found. 5993 */ 5994 enum ice_status 5995 ice_add_vsi_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u16 vsig) 5996 { 5997 struct ice_chs_chg *tmp, *del; 5998 struct LIST_HEAD_TYPE chg; 5999 enum ice_status status; 6000 6001 /* if target VSIG is default the move is invalid */ 6002 if ((vsig & ICE_VSIG_IDX_M) == ICE_DEFAULT_VSIG) 6003 return ICE_ERR_PARAM; 6004 6005 INIT_LIST_HEAD(&chg); 6006 6007 /* move VSI to the VSIG that matches */ 6008 status = ice_move_vsi(hw, blk, vsi, vsig, &chg); 6009 /* update hardware if success */ 6010 if (!status) 6011 status = ice_upd_prof_hw(hw, blk, &chg); 6012 6013 LIST_FOR_EACH_ENTRY_SAFE(del, tmp, &chg, ice_chs_chg, list_entry) { 6014 LIST_DEL(&del->list_entry); 6015 ice_free(hw, del); 6016 } 6017 6018 return status; 6019 } 6020 6021 /** 6022 * ice_add_prof_id_flow - add profile flow 6023 * @hw: pointer to the HW struct 6024 * @blk: hardware block 6025 * @vsi: the VSI to enable with the profile specified by ID 6026 * @hdl: profile handle 6027 * 6028 * Calling this function will update the hardware tables to enable the 6029 * profile indicated by the ID parameter for the VSIs specified in the VSI 6030 * array. Once successfully called, the flow will be enabled. 6031 */ 6032 enum ice_status 6033 ice_add_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl) 6034 { 6035 struct ice_vsig_prof *tmp1, *del1; 6036 struct LIST_HEAD_TYPE union_lst; 6037 struct ice_chs_chg *tmp, *del; 6038 struct LIST_HEAD_TYPE chg; 6039 enum ice_status status; 6040 u16 vsig; 6041 6042 INIT_LIST_HEAD(&union_lst); 6043 INIT_LIST_HEAD(&chg); 6044 6045 /* Get profile */ 6046 status = ice_get_prof(hw, blk, hdl, &chg); 6047 if (status) 6048 return status; 6049 6050 /* determine if VSI is already part of a VSIG */ 6051 status = ice_vsig_find_vsi(hw, blk, vsi, &vsig); 6052 if (!status && vsig) { 6053 bool only_vsi; 6054 u16 or_vsig; 6055 u16 ref; 6056 6057 /* found in VSIG */ 6058 or_vsig = vsig; 6059 6060 /* make sure that there is no overlap/conflict between the new 6061 * characteristics and the existing ones; we don't support that 6062 * scenario 6063 */ 6064 if (ice_has_prof_vsig(hw, blk, vsig, hdl)) { 6065 status = ICE_ERR_ALREADY_EXISTS; 6066 goto err_ice_add_prof_id_flow; 6067 } 6068 6069 /* last VSI in the VSIG? */ 6070 status = ice_vsig_get_ref(hw, blk, vsig, &ref); 6071 if (status) 6072 goto err_ice_add_prof_id_flow; 6073 only_vsi = (ref == 1); 6074 6075 /* create a union of the current profiles and the one being 6076 * added 6077 */ 6078 status = ice_get_profs_vsig(hw, blk, vsig, &union_lst); 6079 if (status) 6080 goto err_ice_add_prof_id_flow; 6081 6082 status = ice_add_prof_to_lst(hw, blk, &union_lst, hdl); 6083 if (status) 6084 goto err_ice_add_prof_id_flow; 6085 6086 /* search for an existing VSIG with an exact charc match */ 6087 status = ice_find_dup_props_vsig(hw, blk, &union_lst, &vsig); 6088 if (!status) { 6089 /* move VSI to the VSIG that matches */ 6090 status = ice_move_vsi(hw, blk, vsi, vsig, &chg); 6091 if (status) 6092 goto err_ice_add_prof_id_flow; 6093 6094 /* VSI has been moved out of or_vsig. If the or_vsig had 6095 * only that VSI it is now empty and can be removed. 6096 */ 6097 if (only_vsi) { 6098 status = ice_rem_vsig(hw, blk, or_vsig, &chg); 6099 if (status) 6100 goto err_ice_add_prof_id_flow; 6101 } 6102 } else if (only_vsi) { 6103 /* If the original VSIG only contains one VSI, then it 6104 * will be the requesting VSI. In this case the VSI is 6105 * not sharing entries and we can simply add the new 6106 * profile to the VSIG. 6107 */ 6108 status = ice_add_prof_id_vsig(hw, blk, vsig, hdl, false, 6109 &chg); 6110 if (status) 6111 goto err_ice_add_prof_id_flow; 6112 6113 /* Adjust priorities */ 6114 status = ice_adj_prof_priorities(hw, blk, vsig, &chg); 6115 if (status) 6116 goto err_ice_add_prof_id_flow; 6117 } else { 6118 /* No match, so we need a new VSIG */ 6119 status = ice_create_vsig_from_lst(hw, blk, vsi, 6120 &union_lst, &vsig, 6121 &chg); 6122 if (status) 6123 goto err_ice_add_prof_id_flow; 6124 6125 /* Adjust priorities */ 6126 status = ice_adj_prof_priorities(hw, blk, vsig, &chg); 6127 if (status) 6128 goto err_ice_add_prof_id_flow; 6129 } 6130 } else { 6131 /* need to find or add a VSIG */ 6132 /* search for an existing VSIG with an exact charc match */ 6133 if (ice_find_prof_vsig(hw, blk, hdl, &vsig)) { 6134 /* found an exact match */ 6135 /* add or move VSI to the VSIG that matches */ 6136 status = ice_move_vsi(hw, blk, vsi, vsig, &chg); 6137 if (status) 6138 goto err_ice_add_prof_id_flow; 6139 } else { 6140 /* we did not find an exact match */ 6141 /* we need to add a VSIG */ 6142 status = ice_create_prof_id_vsig(hw, blk, vsi, hdl, 6143 &chg); 6144 if (status) 6145 goto err_ice_add_prof_id_flow; 6146 } 6147 } 6148 6149 /* update hardware */ 6150 if (!status) 6151 status = ice_upd_prof_hw(hw, blk, &chg); 6152 6153 err_ice_add_prof_id_flow: 6154 LIST_FOR_EACH_ENTRY_SAFE(del, tmp, &chg, ice_chs_chg, list_entry) { 6155 LIST_DEL(&del->list_entry); 6156 ice_free(hw, del); 6157 } 6158 6159 LIST_FOR_EACH_ENTRY_SAFE(del1, tmp1, &union_lst, ice_vsig_prof, list) { 6160 LIST_DEL(&del1->list); 6161 ice_free(hw, del1); 6162 } 6163 6164 return status; 6165 } 6166 6167 /** 6168 * ice_rem_prof_from_list - remove a profile from list 6169 * @hw: pointer to the HW struct 6170 * @lst: list to remove the profile from 6171 * @hdl: the profile handle indicating the profile to remove 6172 */ 6173 static enum ice_status 6174 ice_rem_prof_from_list(struct ice_hw *hw, struct LIST_HEAD_TYPE *lst, u64 hdl) 6175 { 6176 struct ice_vsig_prof *ent, *tmp; 6177 6178 LIST_FOR_EACH_ENTRY_SAFE(ent, tmp, lst, ice_vsig_prof, list) 6179 if (ent->profile_cookie == hdl) { 6180 LIST_DEL(&ent->list); 6181 ice_free(hw, ent); 6182 return ICE_SUCCESS; 6183 } 6184 6185 return ICE_ERR_DOES_NOT_EXIST; 6186 } 6187 6188 /** 6189 * ice_rem_prof_id_flow - remove flow 6190 * @hw: pointer to the HW struct 6191 * @blk: hardware block 6192 * @vsi: the VSI from which to remove the profile specified by ID 6193 * @hdl: profile tracking handle 6194 * 6195 * Calling this function will update the hardware tables to remove the 6196 * profile indicated by the ID parameter for the VSIs specified in the VSI 6197 * array. Once successfully called, the flow will be disabled. 6198 */ 6199 enum ice_status 6200 ice_rem_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl) 6201 { 6202 struct ice_vsig_prof *tmp1, *del1; 6203 struct LIST_HEAD_TYPE chg, copy; 6204 struct ice_chs_chg *tmp, *del; 6205 enum ice_status status; 6206 u16 vsig; 6207 6208 INIT_LIST_HEAD(©); 6209 INIT_LIST_HEAD(&chg); 6210 6211 /* determine if VSI is already part of a VSIG */ 6212 status = ice_vsig_find_vsi(hw, blk, vsi, &vsig); 6213 if (!status && vsig) { 6214 bool last_profile; 6215 bool only_vsi; 6216 u16 ref; 6217 6218 /* found in VSIG */ 6219 last_profile = ice_vsig_prof_id_count(hw, blk, vsig) == 1; 6220 status = ice_vsig_get_ref(hw, blk, vsig, &ref); 6221 if (status) 6222 goto err_ice_rem_prof_id_flow; 6223 only_vsi = (ref == 1); 6224 6225 if (only_vsi) { 6226 /* If the original VSIG only contains one reference, 6227 * which will be the requesting VSI, then the VSI is not 6228 * sharing entries and we can simply remove the specific 6229 * characteristics from the VSIG. 6230 */ 6231 6232 if (last_profile) { 6233 /* If there are no profiles left for this VSIG, 6234 * then simply remove the VSIG. 6235 */ 6236 status = ice_rem_vsig(hw, blk, vsig, &chg); 6237 if (status) 6238 goto err_ice_rem_prof_id_flow; 6239 } else { 6240 status = ice_rem_prof_id_vsig(hw, blk, vsig, 6241 hdl, &chg); 6242 if (status) 6243 goto err_ice_rem_prof_id_flow; 6244 6245 /* Adjust priorities */ 6246 status = ice_adj_prof_priorities(hw, blk, vsig, 6247 &chg); 6248 if (status) 6249 goto err_ice_rem_prof_id_flow; 6250 } 6251 6252 } else { 6253 /* Make a copy of the VSIG's list of Profiles */ 6254 status = ice_get_profs_vsig(hw, blk, vsig, ©); 6255 if (status) 6256 goto err_ice_rem_prof_id_flow; 6257 6258 /* Remove specified profile entry from the list */ 6259 status = ice_rem_prof_from_list(hw, ©, hdl); 6260 if (status) 6261 goto err_ice_rem_prof_id_flow; 6262 6263 if (LIST_EMPTY(©)) { 6264 status = ice_move_vsi(hw, blk, vsi, 6265 ICE_DEFAULT_VSIG, &chg); 6266 if (status) 6267 goto err_ice_rem_prof_id_flow; 6268 6269 } else if (!ice_find_dup_props_vsig(hw, blk, ©, 6270 &vsig)) { 6271 /* found an exact match */ 6272 /* add or move VSI to the VSIG that matches */ 6273 /* Search for a VSIG with a matching profile 6274 * list 6275 */ 6276 6277 /* Found match, move VSI to the matching VSIG */ 6278 status = ice_move_vsi(hw, blk, vsi, vsig, &chg); 6279 if (status) 6280 goto err_ice_rem_prof_id_flow; 6281 } else { 6282 /* since no existing VSIG supports this 6283 * characteristic pattern, we need to create a 6284 * new VSIG and TCAM entries 6285 */ 6286 status = ice_create_vsig_from_lst(hw, blk, vsi, 6287 ©, &vsig, 6288 &chg); 6289 if (status) 6290 goto err_ice_rem_prof_id_flow; 6291 6292 /* Adjust priorities */ 6293 status = ice_adj_prof_priorities(hw, blk, vsig, 6294 &chg); 6295 if (status) 6296 goto err_ice_rem_prof_id_flow; 6297 } 6298 } 6299 } else { 6300 status = ICE_ERR_DOES_NOT_EXIST; 6301 } 6302 6303 /* update hardware tables */ 6304 if (!status) 6305 status = ice_upd_prof_hw(hw, blk, &chg); 6306 6307 err_ice_rem_prof_id_flow: 6308 LIST_FOR_EACH_ENTRY_SAFE(del, tmp, &chg, ice_chs_chg, list_entry) { 6309 LIST_DEL(&del->list_entry); 6310 ice_free(hw, del); 6311 } 6312 6313 LIST_FOR_EACH_ENTRY_SAFE(del1, tmp1, ©, ice_vsig_prof, list) { 6314 LIST_DEL(&del1->list); 6315 ice_free(hw, del1); 6316 } 6317 6318 return status; 6319 } 6320