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