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