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